Merge f9f864883d into 45b0271ded
				
					
				
			This commit is contained in:
		
						commit
						32a7e62c6c
					
				| 
						 | 
					@ -87,6 +87,7 @@ objc_library(
 | 
				
			||||||
        "//mediapipe/framework:calculator_cc_proto",
 | 
					        "//mediapipe/framework:calculator_cc_proto",
 | 
				
			||||||
        "//mediapipe/tasks/cc/core:mediapipe_builtin_op_resolver",
 | 
					        "//mediapipe/tasks/cc/core:mediapipe_builtin_op_resolver",
 | 
				
			||||||
        "//mediapipe/tasks/cc/core:task_runner",
 | 
					        "//mediapipe/tasks/cc/core:task_runner",
 | 
				
			||||||
 | 
					        "//mediapipe/tasks/ios/common:MPPCommon",
 | 
				
			||||||
        "//mediapipe/tasks/ios/common/utils:MPPCommonUtils",
 | 
					        "//mediapipe/tasks/ios/common/utils:MPPCommonUtils",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@
 | 
				
			||||||
// limitations under the License.
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#import "mediapipe/tasks/ios/core/sources/MPPTaskRunner.h"
 | 
					#import "mediapipe/tasks/ios/core/sources/MPPTaskRunner.h"
 | 
				
			||||||
 | 
					#import "mediapipe/tasks/ios/common/sources/MPPCommon.h"
 | 
				
			||||||
#import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h"
 | 
					#import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.h"
 | 
					#include "mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.h"
 | 
				
			||||||
| 
						 | 
					@ -28,6 +29,7 @@ using TaskRunnerCpp = ::mediapipe::tasks::core::TaskRunner;
 | 
				
			||||||
@interface MPPTaskRunner () {
 | 
					@interface MPPTaskRunner () {
 | 
				
			||||||
  // Cpp Task Runner
 | 
					  // Cpp Task Runner
 | 
				
			||||||
  std::unique_ptr<TaskRunnerCpp> _cppTaskRunner;
 | 
					  std::unique_ptr<TaskRunnerCpp> _cppTaskRunner;
 | 
				
			||||||
 | 
					  BOOL _initializedWithPacketsCallback;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@end
 | 
					@end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,6 +48,7 @@ using TaskRunnerCpp = ::mediapipe::tasks::core::TaskRunner;
 | 
				
			||||||
      return nil;
 | 
					      return nil;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    _cppTaskRunner = std::move(taskRunnerResult.value());
 | 
					    _cppTaskRunner = std::move(taskRunnerResult.value());
 | 
				
			||||||
 | 
					    _initializedWithPacketsCallback = packetsCallback ? YES : NO;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return self;
 | 
					  return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -59,7 +62,20 @@ using TaskRunnerCpp = ::mediapipe::tasks::core::TaskRunner;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (BOOL)sendPacketMap:(const PacketMap &)packetMap error:(NSError **)error {
 | 
					- (BOOL)sendPacketMap:(const PacketMap &)packetMap error:(NSError **)error {
 | 
				
			||||||
 | 
					  if (!_initializedWithPacketsCallback) {
 | 
				
			||||||
 | 
					    [MPPCommonUtils
 | 
				
			||||||
 | 
					        createCustomError:error
 | 
				
			||||||
 | 
					                 withCode:MPPTasksErrorCodeFailedPreconditionError
 | 
				
			||||||
 | 
					              description:[NSString
 | 
				
			||||||
 | 
					                              stringWithFormat:@"This method can only be called if the task is "
 | 
				
			||||||
 | 
					                                               @"running in a stream mode and an object of a class "
 | 
				
			||||||
 | 
					                                               @"is provided as the delegate in the task options "
 | 
				
			||||||
 | 
					                                               @"to receive the results asynchronously."]];
 | 
				
			||||||
 | 
					    return NO;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  absl::Status sendStatus = _cppTaskRunner->Send(packetMap);
 | 
					  absl::Status sendStatus = _cppTaskRunner->Send(packetMap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return [MPPCommonUtils checkCppError:sendStatus toError:error];
 | 
					  return [MPPCommonUtils checkCppError:sendStatus toError:error];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -439,7 +439,7 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma mark Running Mode Tests
 | 
					#pragma mark Running Mode Tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (void)testCreateImageClassifierFailsWithDelegateInNonLiveStreamMode {
 | 
					- (void)testCreateImageClassifierSucceedsWithDelegateInNonLiveStreamMode {
 | 
				
			||||||
  MPPRunningMode runningModesToTest[] = {MPPRunningModeImage, MPPRunningModeVideo};
 | 
					  MPPRunningMode runningModesToTest[] = {MPPRunningModeImage, MPPRunningModeVideo};
 | 
				
			||||||
  for (int i = 0; i < sizeof(runningModesToTest) / sizeof(runningModesToTest[0]); i++) {
 | 
					  for (int i = 0; i < sizeof(runningModesToTest) / sizeof(runningModesToTest[0]); i++) {
 | 
				
			||||||
    MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName];
 | 
					    MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName];
 | 
				
			||||||
| 
						 | 
					@ -447,36 +447,20 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation";
 | 
				
			||||||
    options.runningMode = runningModesToTest[i];
 | 
					    options.runningMode = runningModesToTest[i];
 | 
				
			||||||
    options.imageClassifierLiveStreamDelegate = self;
 | 
					    options.imageClassifierLiveStreamDelegate = self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [self
 | 
					    MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options
 | 
				
			||||||
        assertCreateImageClassifierWithOptions:options
 | 
					                                                                                error:nil];
 | 
				
			||||||
                        failsWithExpectedError:
 | 
					    XCTAssertNotNil(imageClassifier);
 | 
				
			||||||
                            [NSError
 | 
					 | 
				
			||||||
                                errorWithDomain:kExpectedErrorDomain
 | 
					 | 
				
			||||||
                                           code:MPPTasksErrorCodeInvalidArgumentError
 | 
					 | 
				
			||||||
                                       userInfo:@{
 | 
					 | 
				
			||||||
                                         NSLocalizedDescriptionKey :
 | 
					 | 
				
			||||||
                                             @"The vision task is in image or video mode. The "
 | 
					 | 
				
			||||||
                                             @"delegate must not be set in the task's options."
 | 
					 | 
				
			||||||
                                       }]];
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (void)testCreateImageClassifierFailsWithMissingDelegateInLiveStreamMode {
 | 
					- (void)testCreateImageClassifieSucceedsWithMissingDelegateInLiveStreamMode {
 | 
				
			||||||
  MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName];
 | 
					  MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  options.runningMode = MPPRunningModeLiveStream;
 | 
					  options.runningMode = MPPRunningModeLiveStream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [self assertCreateImageClassifierWithOptions:options
 | 
					  MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options
 | 
				
			||||||
                        failsWithExpectedError:
 | 
					                                                                              error:nil];
 | 
				
			||||||
                            [NSError errorWithDomain:kExpectedErrorDomain
 | 
					  XCTAssertNotNil(imageClassifier);
 | 
				
			||||||
                                                code:MPPTasksErrorCodeInvalidArgumentError
 | 
					 | 
				
			||||||
                                            userInfo:@{
 | 
					 | 
				
			||||||
                                              NSLocalizedDescriptionKey :
 | 
					 | 
				
			||||||
                                                  @"The vision task is in live stream mode. An "
 | 
					 | 
				
			||||||
                                                  @"object must be set as the delegate of the task "
 | 
					 | 
				
			||||||
                                                  @"in its options to ensure asynchronous delivery "
 | 
					 | 
				
			||||||
                                                  @"of results."
 | 
					 | 
				
			||||||
                                            }]];
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (void)testClassifyFailsWithCallingWrongApiInImageMode {
 | 
					- (void)testClassifyFailsWithCallingWrongApiInImageMode {
 | 
				
			||||||
| 
						 | 
					@ -614,6 +598,30 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (void)testClassifyFailsWithMissingDelegateInLiveStreamMode {
 | 
				
			||||||
 | 
					  MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName];
 | 
				
			||||||
 | 
					  options.runningMode = MPPRunningModeLiveStream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MPPImageClassifier *imageClassifier = [self imageClassifierWithOptionsSucceeds:options];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NSError *expectedError =
 | 
				
			||||||
 | 
					      [NSError errorWithDomain:kExpectedErrorDomain
 | 
				
			||||||
 | 
					                          code:MPPTasksErrorCodeFailedPreconditionError
 | 
				
			||||||
 | 
					                      userInfo:@{
 | 
				
			||||||
 | 
					                        NSLocalizedDescriptionKey :
 | 
				
			||||||
 | 
					                            @"This method can only be called if the task is running in a stream "
 | 
				
			||||||
 | 
					                            @"mode and an object of a class is provided as the delegate in the "
 | 
				
			||||||
 | 
					                            @"task options to receive the results asynchronously."
 | 
				
			||||||
 | 
					                      }];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MPPImage *image = [self imageWithFileInfo:kBurgerImage];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NSError *error = nil;
 | 
				
			||||||
 | 
					  XCTAssertFalse([imageClassifier classifyAsyncImage:image timestampInMilliseconds:1 error:&error]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AssertEqualErrors(error, expectedError);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (void)testClassifyWithOutOfOrderTimestampsAndLiveStreamModeFails {
 | 
					- (void)testClassifyWithOutOfOrderTimestampsAndLiveStreamModeFails {
 | 
				
			||||||
  MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName];
 | 
					  MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,38 +51,13 @@ static NSString *const kTaskPrefix = @"com.mediapipe.tasks.vision";
 | 
				
			||||||
                                           runningMode:(MPPRunningMode)runningMode
 | 
					                                           runningMode:(MPPRunningMode)runningMode
 | 
				
			||||||
                                       packetsCallback:(PacketsCallback)packetsCallback
 | 
					                                       packetsCallback:(PacketsCallback)packetsCallback
 | 
				
			||||||
                                                 error:(NSError **)error {
 | 
					                                                 error:(NSError **)error {
 | 
				
			||||||
  switch (runningMode) {
 | 
					
 | 
				
			||||||
    case MPPRunningModeImage:
 | 
					  if (_runningMode > MPPRunningModeLiveStream) {
 | 
				
			||||||
    case MPPRunningModeVideo: {
 | 
					 | 
				
			||||||
      if (packetsCallback) {
 | 
					 | 
				
			||||||
        [MPPCommonUtils createCustomError:error
 | 
					 | 
				
			||||||
                                 withCode:MPPTasksErrorCodeInvalidArgumentError
 | 
					 | 
				
			||||||
                              description:@"The vision task is in image or video mode. The "
 | 
					 | 
				
			||||||
                                          @"delegate must not be set in the task's options."];
 | 
					 | 
				
			||||||
        return nil;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    case MPPRunningModeLiveStream: {
 | 
					 | 
				
			||||||
      if (!packetsCallback) {
 | 
					 | 
				
			||||||
        [MPPCommonUtils
 | 
					 | 
				
			||||||
            createCustomError:error
 | 
					 | 
				
			||||||
                     withCode:MPPTasksErrorCodeInvalidArgumentError
 | 
					 | 
				
			||||||
                  description:
 | 
					 | 
				
			||||||
                      @"The vision task is in live stream mode. An object must be set as the "
 | 
					 | 
				
			||||||
                      @"delegate of the task in its options to ensure asynchronous delivery of "
 | 
					 | 
				
			||||||
                      @"results."];
 | 
					 | 
				
			||||||
        return nil;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    default: {
 | 
					 | 
				
			||||||
      [MPPCommonUtils createCustomError:error
 | 
					      [MPPCommonUtils createCustomError:error
 | 
				
			||||||
                               withCode:MPPTasksErrorCodeInvalidArgumentError
 | 
					                               withCode:MPPTasksErrorCodeInvalidArgumentError
 | 
				
			||||||
                            description:@"Unrecognized running mode"];
 | 
					                            description:@"Unrecognized running mode"];
 | 
				
			||||||
      return nil;
 | 
					      return nil;
 | 
				
			||||||
    }                                     
 | 
					    }                                     
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  _runningMode = runningMode;
 | 
					  _runningMode = runningMode;
 | 
				
			||||||
  self = [super initWithCalculatorGraphConfig:graphConfig
 | 
					  self = [super initWithCalculatorGraphConfig:graphConfig
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,11 +64,6 @@ static const int kMicroSecondsPerMilliSecond = 1000;
 | 
				
			||||||
@implementation MPPImageClassifier
 | 
					@implementation MPPImageClassifier
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (void)processLiveStreamResult:(absl::StatusOr<PacketMap>)liveStreamResult {
 | 
					- (void)processLiveStreamResult:(absl::StatusOr<PacketMap>)liveStreamResult {
 | 
				
			||||||
  if (![self.imageClassifierLiveStreamDelegate
 | 
					 | 
				
			||||||
          respondsToSelector:@selector
 | 
					 | 
				
			||||||
          (imageClassifier:didFinishClassificationWithResult:timestampInMilliseconds:error:)]) {
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
  NSError *callbackError = nil;
 | 
					  NSError *callbackError = nil;
 | 
				
			||||||
  if (![MPPCommonUtils checkCppError:liveStreamResult.status() toError:&callbackError]) {
 | 
					  if (![MPPCommonUtils checkCppError:liveStreamResult.status() toError:&callbackError]) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
 | 
				
			||||||
NS_SWIFT_NAME(ImageClassifierLiveStreamDelegate)
 | 
					NS_SWIFT_NAME(ImageClassifierLiveStreamDelegate)
 | 
				
			||||||
@protocol MPPImageClassifierLiveStreamDelegate <NSObject>
 | 
					@protocol MPPImageClassifierLiveStreamDelegate <NSObject>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@optional
 | 
					@required
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * This method notifies a delegate that the results of asynchronous classification of
 | 
					 * This method notifies a delegate that the results of asynchronous classification of
 | 
				
			||||||
 * an image submitted to the `ImageClassifier` is available.
 | 
					 * an image submitted to the `ImageClassifier` is available.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user