Commit bba14896 authored by junweifu's avatar junweifu Committed by Commit Bot

ShapeDetection: Move VisionAPIAsyncRequestMac to a common location

Only move code without modifying the implementation so that Barcode Detection
can reuse it.

BUG=848182

Cq-Include-Trybots: luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win10_chromium_x64_rel_ng
Change-Id: Ia04a56efbd2ace4eb05f0ebaa4e341ef7a032fa4
Reviewed-on: https://chromium-review.googlesource.com/1128625
Commit-Queue: Junwei Fu <junwei.fu@intel.com>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575522}
parent f4f56e28
......@@ -6,8 +6,13 @@
#define SERVICES_SHAPE_DETECTION_DETECTION_UTILS_MAC_H_
#import <CoreImage/CoreImage.h>
#include <memory>
#include "base/callback.h"
#include "base/mac/availability.h"
#include "base/mac/scoped_nsobject.h"
#include "base/mac/sdk_forward_declarations.h"
#include "base/macros.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/geometry/rect_f.h"
......@@ -20,6 +25,36 @@ base::scoped_nsobject<CIImage> CreateCIImageFromSkBitmap(
gfx::RectF ConvertCGToGfxCoordinates(CGRect bounds, int height);
// This class submits an image analysis request for asynchronous execution on a
// dispatch queue with default priority.
class API_AVAILABLE(macos(10.13)) VisionAPIAsyncRequestMac {
public:
// A callback run when the asynchronous execution completes. The callback is
// repeating for the instance.
using Callback =
base::RepeatingCallback<void(VNRequest* request, NSError* error)>;
~VisionAPIAsyncRequestMac();
// Creates an VisionAPIAsyncRequestMac instance which sets |callback| to be
// called when the asynchronous action completes.
static std::unique_ptr<VisionAPIAsyncRequestMac> Create(Class request_class,
Callback callback);
// Processes asynchronously an image analysis request and returns results with
// |callback_| when the asynchronous request completes, the callers should
// only enqueue one request at a timer.
bool PerformRequest(const SkBitmap& bitmap);
private:
VisionAPIAsyncRequestMac(Callback callback, Class request_class);
base::scoped_nsobject<VNRequest> request_;
const Callback callback_;
DISALLOW_COPY_AND_ASSIGN(VisionAPIAsyncRequestMac);
};
} // namespace shape_detection
#endif // SERVICES_SHAPE_DETECTION_DETECTION_UTILS_MAC_H_
......@@ -4,8 +4,16 @@
#include "services/shape_detection/detection_utils_mac.h"
#include <vector>
#include "base/bind.h"
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/ptr_util.h"
#include "base/numerics/checked_math.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "third_party/skia/include/utils/mac/SkCGUtils.h"
namespace shape_detection {
......@@ -46,4 +54,63 @@ gfx::RectF ConvertCGToGfxCoordinates(CGRect bounds, int height) {
bounds.size.width, bounds.size.height);
}
// static
// Creates an VisionAPIAsyncRequestMac instance which sets |callback| to be
// called when the asynchronous action completes.
std::unique_ptr<VisionAPIAsyncRequestMac> VisionAPIAsyncRequestMac::Create(
Class request_class,
Callback callback) {
return base::WrapUnique(
new VisionAPIAsyncRequestMac(std::move(callback), request_class));
}
VisionAPIAsyncRequestMac::VisionAPIAsyncRequestMac(Callback callback,
Class request_class)
: callback_(std::move(callback)) {
DCHECK(callback_);
scoped_refptr<base::SequencedTaskRunner> task_runner =
base::SequencedTaskRunnerHandle::Get();
const auto handler = ^(VNRequest* request, NSError* error) {
task_runner->PostTask(FROM_HERE, base::BindOnce(callback_, request, error));
};
request_.reset([[request_class alloc] initWithCompletionHandler:handler]);
}
VisionAPIAsyncRequestMac::~VisionAPIAsyncRequestMac() = default;
// Processes asynchronously an image analysis request and returns results with
// |callback_| when the asynchronous request completes.
bool VisionAPIAsyncRequestMac::PerformRequest(const SkBitmap& bitmap) {
Class image_handler_class = NSClassFromString(@"VNImageRequestHandler");
if (!image_handler_class) {
DLOG(ERROR) << "Failed to load VNImageRequestHandler class";
return false;
}
base::scoped_nsobject<CIImage> ci_image = CreateCIImageFromSkBitmap(bitmap);
if (!ci_image) {
DLOG(ERROR) << "Failed to create image from SkBitmap";
return false;
}
base::scoped_nsobject<VNImageRequestHandler> image_handler(
[[image_handler_class alloc] initWithCIImage:ci_image options:@{}]);
if (!image_handler) {
DLOG(ERROR) << "Failed to create image request handler";
return false;
}
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError* ns_error = nil;
if ([image_handler performRequests:@[ request_ ] error:&ns_error])
return;
DLOG(ERROR) << base::SysNSStringToUTF8([ns_error localizedDescription]);
});
return true;
}
} // namespace shape_detection
......@@ -9,11 +9,11 @@
#include <utility>
#include "base/mac/availability.h"
#include "base/mac/scoped_nsobject.h"
#include "base/mac/sdk_forward_declarations.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/shape_detection/detection_utils_mac.h"
#include "services/shape_detection/public/mojom/facedetection.mojom.h"
class SkBitmap;
......@@ -36,7 +36,6 @@ class API_AVAILABLE(macos(10.13)) FaceDetectionImplMacVision
}
private:
class VisionAPIAsyncRequestMac;
void OnFacesDetected(VNRequest* request, NSError* error);
CGSize image_size_;
......
......@@ -7,12 +7,8 @@
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/sys_string_conversions.h"
#include "services/shape_detection/detection_utils_mac.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace shape_detection {
......@@ -37,81 +33,6 @@ mojom::LandmarkPtr BuildLandmark(VNFaceLandmarkRegion2D* landmark_region,
}
}
// The VisionAPIAsyncRequestMac class submits an image analysis request for
// asynchronous execution on a dispatch queue with default priority.
class API_AVAILABLE(macos(10.13))
FaceDetectionImplMacVision::VisionAPIAsyncRequestMac {
public:
// A callback run when the asynchronous execution completes. The callback is
// repeating for the instance.
using Callback =
base::RepeatingCallback<void(VNRequest* request, NSError* error)>;
~VisionAPIAsyncRequestMac() = default;
// Creates an VisionAPIAsyncRequestMac instance which sets |callback| to be
// called when the asynchronous action completes.
static std::unique_ptr<VisionAPIAsyncRequestMac> Create(Class request_class,
Callback callback) {
return base::WrapUnique(
new VisionAPIAsyncRequestMac(std::move(callback), request_class));
}
// Processes asynchronously an image analysis request and returns results with
// |callback_| when the asynchronous request completes.
bool PerformRequest(const SkBitmap& bitmap) {
Class image_handler_class = NSClassFromString(@"VNImageRequestHandler");
if (!image_handler_class) {
DLOG(ERROR) << "Failed to load VNImageRequestHandler class";
return false;
}
base::scoped_nsobject<CIImage> ci_image = CreateCIImageFromSkBitmap(bitmap);
if (!ci_image) {
DLOG(ERROR) << "Failed to create image from SkBitmap";
return false;
}
base::scoped_nsobject<VNImageRequestHandler> image_handler(
[[image_handler_class alloc] initWithCIImage:ci_image options:@{}]);
if (!image_handler) {
DLOG(ERROR) << "Failed to create image request handler";
return false;
}
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError* ns_error = nil;
if ([image_handler performRequests:@[ request_ ] error:&ns_error])
return;
DLOG(ERROR) << base::SysNSStringToUTF8(
[ns_error localizedDescription]);
});
return true;
}
private:
VisionAPIAsyncRequestMac(Callback callback, Class request_class)
: callback_(std::move(callback)) {
DCHECK(callback_);
scoped_refptr<base::SequencedTaskRunner> task_runner =
base::SequencedTaskRunnerHandle::Get();
const auto handler = ^(VNRequest* request, NSError* error) {
task_runner->PostTask(FROM_HERE,
base::BindOnce(callback_, request, error));
};
request_.reset([[request_class alloc] initWithCompletionHandler:handler]);
}
base::scoped_nsobject<VNRequest> request_;
const Callback callback_;
DISALLOW_COPY_AND_ASSIGN(VisionAPIAsyncRequestMac);
};
FaceDetectionImplMacVision::FaceDetectionImplMacVision() : weak_factory_(this) {
Class request_class = NSClassFromString(@"VNDetectFaceLandmarksRequest");
if (!request_class) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment