This commit is contained in:
priankakariatyml 2023-08-30 19:32:44 +02:00 committed by GitHub
commit 32a7e62c6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 55 additions and 60 deletions

View File

@ -87,6 +87,7 @@ objc_library(
"//mediapipe/framework:calculator_cc_proto",
"//mediapipe/tasks/cc/core:mediapipe_builtin_op_resolver",
"//mediapipe/tasks/cc/core:task_runner",
"//mediapipe/tasks/ios/common:MPPCommon",
"//mediapipe/tasks/ios/common/utils:MPPCommonUtils",
],
)

View File

@ -13,6 +13,7 @@
// limitations under the License.
#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"
#include "mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.h"
@ -28,6 +29,7 @@ using TaskRunnerCpp = ::mediapipe::tasks::core::TaskRunner;
@interface MPPTaskRunner () {
// Cpp Task Runner
std::unique_ptr<TaskRunnerCpp> _cppTaskRunner;
BOOL _initializedWithPacketsCallback;
}
@end
@ -46,6 +48,7 @@ using TaskRunnerCpp = ::mediapipe::tasks::core::TaskRunner;
return nil;
}
_cppTaskRunner = std::move(taskRunnerResult.value());
_initializedWithPacketsCallback = packetsCallback ? YES : NO;
}
return self;
}
@ -59,7 +62,20 @@ using TaskRunnerCpp = ::mediapipe::tasks::core::TaskRunner;
}
- (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);
return [MPPCommonUtils checkCppError:sendStatus toError:error];
}

View File

@ -439,7 +439,7 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation";
#pragma mark Running Mode Tests
- (void)testCreateImageClassifierFailsWithDelegateInNonLiveStreamMode {
- (void)testCreateImageClassifierSucceedsWithDelegateInNonLiveStreamMode {
MPPRunningMode runningModesToTest[] = {MPPRunningModeImage, MPPRunningModeVideo};
for (int i = 0; i < sizeof(runningModesToTest) / sizeof(runningModesToTest[0]); i++) {
MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName];
@ -447,36 +447,20 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation";
options.runningMode = runningModesToTest[i];
options.imageClassifierLiveStreamDelegate = self;
[self
assertCreateImageClassifierWithOptions:options
failsWithExpectedError:
[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."
}]];
MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options
error:nil];
XCTAssertNotNil(imageClassifier);
}
}
- (void)testCreateImageClassifierFailsWithMissingDelegateInLiveStreamMode {
- (void)testCreateImageClassifieSucceedsWithMissingDelegateInLiveStreamMode {
MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName];
options.runningMode = MPPRunningModeLiveStream;
[self assertCreateImageClassifierWithOptions:options
failsWithExpectedError:
[NSError errorWithDomain:kExpectedErrorDomain
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."
}]];
MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options
error:nil];
XCTAssertNotNil(imageClassifier);
}
- (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 {
MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName];

View File

@ -51,39 +51,14 @@ static NSString *const kTaskPrefix = @"com.mediapipe.tasks.vision";
runningMode:(MPPRunningMode)runningMode
packetsCallback:(PacketsCallback)packetsCallback
error:(NSError **)error {
switch (runningMode) {
case MPPRunningModeImage:
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: {
if (_runningMode > MPPRunningModeLiveStream) {
[MPPCommonUtils createCustomError:error
withCode:MPPTasksErrorCodeInvalidArgumentError
description:@"Unrecognized running mode"];
return nil;
}
}
}
_runningMode = runningMode;
self = [super initWithCalculatorGraphConfig:graphConfig
packetsCallback:packetsCallback

View File

@ -64,12 +64,7 @@ static const int kMicroSecondsPerMilliSecond = 1000;
@implementation MPPImageClassifier
- (void)processLiveStreamResult:(absl::StatusOr<PacketMap>)liveStreamResult {
if (![self.imageClassifierLiveStreamDelegate
respondsToSelector:@selector
(imageClassifier:didFinishClassificationWithResult:timestampInMilliseconds:error:)]) {
return;
}
NSError *callbackError = nil;
if (![MPPCommonUtils checkCppError:liveStreamResult.status() toError:&callbackError]) {
dispatch_async(_callbackQueue, ^{

View File

@ -33,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
NS_SWIFT_NAME(ImageClassifierLiveStreamDelegate)
@protocol MPPImageClassifierLiveStreamDelegate <NSObject>
@optional
@required
/**
* This method notifies a delegate that the results of asynchronous classification of
* an image submitted to the `ImageClassifier` is available.