Updated image classifier delegate methods to be dispatched onto a dedicated queue.

This commit is contained in:
Prianka Liz Kariat 2023-05-04 01:00:36 +05:30
parent efbfe93515
commit 546b153f07

View File

@ -39,9 +39,9 @@ static NSString *const kImageOutStreamName = @"image_out";
static NSString *const kImageTag = @"IMAGE"; static NSString *const kImageTag = @"IMAGE";
static NSString *const kNormRectStreamName = @"norm_rect_in"; static NSString *const kNormRectStreamName = @"norm_rect_in";
static NSString *const kNormRectTag = @"NORM_RECT"; static NSString *const kNormRectTag = @"NORM_RECT";
static NSString *const kTaskGraphName = static NSString *const kTaskGraphName =
@"mediapipe.tasks.vision.image_classifier.ImageClassifierGraph"; @"mediapipe.tasks.vision.image_classifier.ImageClassifierGraph";
static NSString *const kTaskName = @"imageClassifier";
#define InputPacketMap(imagePacket, normalizedRectPacket) \ #define InputPacketMap(imagePacket, normalizedRectPacket) \
{ \ { \
@ -61,6 +61,7 @@ static NSString *const kTaskGraphName =
- (instancetype)initWithOptions:(MPPImageClassifierOptions *)options error:(NSError **)error { - (instancetype)initWithOptions:(MPPImageClassifierOptions *)options error:(NSError **)error {
self = [super init]; self = [super init];
NSLog(@"Image Classifier Initializing with dispatch queu and weak self");
if (self) { if (self) {
MPPTaskInfo *taskInfo = [[MPPTaskInfo alloc] MPPTaskInfo *taskInfo = [[MPPTaskInfo alloc]
initWithTaskGraphName:kTaskGraphName initWithTaskGraphName:kTaskGraphName
@ -89,12 +90,15 @@ static NSString *const kTaskGraphName =
// Capturing `self` as weak in order to avoid `self` being kept in memory // Capturing `self` as weak in order to avoid `self` being kept in memory
// and cause a retain cycle, after self is set to `nil`. // and cause a retain cycle, after self is set to `nil`.
MPPImageClassifier *__weak weakSelf = self; MPPImageClassifier *__weak weakSelf = self;
// Create a private serial dispatch queue in which the deleagte method will be called asynchronously. This is to ensure that if the client performs a long running operation in the delegate method, the queue on which the C++ callbacks is invoked is not blocked and is freed up to continue with its operations.
const char *queueName = [MPPVisionTaskRunner uniqueQueueNameWithTaskName:kTaskName];
dispatch_queue_t callbackQueue = dispatch_queue_create(queueName, NULL);
packetsCallback = [=](absl::StatusOr<PacketMap> status_or_packets) { packetsCallback = [=](absl::StatusOr<PacketMap> status_or_packets) {
// Check to ensure that the delegate method is not called on a nil object if (!weakSelf) {
// leading to a segmentation fault, we check `weakSelf` is `nil` before return;
// performing any processing. }
if (!weakSelf || if (![weakSelf.imageClassifierDelegate
![weakSelf.imageClassifierDelegate
respondsToSelector:@selector respondsToSelector:@selector
(imageClassifier: (imageClassifier:
didFinishClassificationWithResult:timestampInMilliseconds:error:)]) { didFinishClassificationWithResult:timestampInMilliseconds:error:)]) {
@ -103,14 +107,16 @@ static NSString *const kTaskGraphName =
NSError *callbackError = nil; NSError *callbackError = nil;
if (![MPPCommonUtils checkCppError:status_or_packets.status() toError:&callbackError]) { if (![MPPCommonUtils checkCppError:status_or_packets.status() toError:&callbackError]) {
dispatch_async(callbackQueue, ^{
[weakSelf.imageClassifierDelegate imageClassifier:weakSelf [weakSelf.imageClassifierDelegate imageClassifier:weakSelf
didFinishClassificationWithResult:nil didFinishClassificationWithResult:nil
timestampInMilliseconds:Timestamp::Unset().Value() timestampInMilliseconds:Timestamp::Unset().Value()
error:callbackError]; error:callbackError];
});
return; return;
} }
PacketMap outputPacketMap = status_or_packets.value(); PacketMap &outputPacketMap = status_or_packets.value();
if (outputPacketMap[kImageOutStreamName.cppString].IsEmpty()) { if (outputPacketMap[kImageOutStreamName.cppString].IsEmpty()) {
return; return;
} }
@ -119,14 +125,16 @@ static NSString *const kTaskGraphName =
[MPPImageClassifierResult imageClassifierResultWithClassificationsPacket: [MPPImageClassifierResult imageClassifierResultWithClassificationsPacket:
outputPacketMap[kClassificationsStreamName.cppString]]; outputPacketMap[kClassificationsStreamName.cppString]];
[weakSelf.imageClassifierDelegate NSInteger timeStampInMilliseconds = outputPacketMap[kImageOutStreamName.cppString]
imageClassifier:weakSelf
didFinishClassificationWithResult:result
timestampInMilliseconds:outputPacketMap[kImageOutStreamName.cppString]
.Timestamp() .Timestamp()
.Value() / .Value() /
kMicroSecondsPerMilliSecond kMicroSecondsPerMilliSecond;
dispatch_async(callbackQueue, ^{
[weakSelf.imageClassifierDelegate imageClassifier:weakSelf
didFinishClassificationWithResult:result
timestampInMilliseconds:timeStampInMilliseconds
error:callbackError]; error:callbackError];
});
}; };
} }