Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: services/shape_detection/face_detection_impl_mac.mm

Issue 2528743002: Shape Detection: Implement FaceDetection on Mac as out-of-process service (Closed)
Patch Set: rockot@ comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "services/shape_detection/face_detection_impl_mac.h"
6
7 #include "base/mac/scoped_cftyperef.h"
8 #include "base/mac/scoped_nsobject.h"
9 #include "base/memory/shared_memory.h"
10 #include "mojo/public/cpp/bindings/strong_binding.h"
11 #include "mojo/public/cpp/system/platform_handle.h"
12
13 namespace shape_detection {
14
15 // kCIFormatRGBA8 is not exposed to public until Mac 10.11. So we define s
mcasas 2016/12/06 00:04:24 nit: s/s/the/ (at the end of the sentence).
xianglu 2016/12/08 01:20:54 Done.
16 // same constant to support RGBA8 format in earlier versions.
17 #if !defined(MAC_OS_X_VERSION_10_11)
mcasas 2016/12/06 00:04:24 We should use here #if MAC_OS_X_VERSION_MIN_REQUI
xianglu 2016/12/08 01:20:54 Done.
18 namespace {
19
20 const int kCIFormatRGBA8 = 24;
21
22 } // anonymous namespace
23 #endif
24
25 void FaceDetectionImpl::Create(blink::mojom::FaceDetectionRequest request) {
26 mojo::MakeStrongBinding(base::MakeUnique<FaceDetectionImplMac>(),
27 std::move(request));
28 }
29
30 FaceDetectionImplMac::FaceDetectionImplMac() {
31 context_.reset([[CIContext alloc] init]);
32 NSDictionary* const opts = @{CIDetectorAccuracy : CIDetectorAccuracyHigh};
33 detector_.reset([[CIDetector detectorOfType:CIDetectorTypeFace
34 context:context_
35 options:opts] retain]);
36 }
37
38 FaceDetectionImplMac::~FaceDetectionImplMac() {}
39
40 void FaceDetectionImplMac::Detect(mojo::ScopedSharedBufferHandle frame_data,
41 uint32_t width,
42 uint32_t height,
43 blink::mojom::FaceDetectorOptionsPtr options,
44 const DetectCallback& callback) {
45 blink::mojom::FaceDetectionResultPtr faces =
46 blink::mojom::FaceDetectionResult::New();
47
48 base::CheckedNumeric<uint32_t> num_pixels =
49 base::CheckedNumeric<uint32_t>(width) * height;
50 base::CheckedNumeric<uint32_t> num_bytes = num_pixels * 4;
51 if (!num_bytes.IsValid()) {
52 DLOG(ERROR) << "Data overflow";
53 callback.Run(std::move(faces));
mcasas 2016/12/06 00:04:23 Having to Run the callback with an empty Face arra
xianglu 2016/12/08 01:20:53 Done.
54 return;
55 }
56
57 base::SharedMemoryHandle memory_handle;
58 size_t memory_size = 0;
59 bool read_only_flag = false;
60 const MojoResult result = mojo::UnwrapSharedMemoryHandle(
61 std::move(frame_data), &memory_handle, &memory_size, &read_only_flag);
62 DCHECK_EQ(MOJO_RESULT_OK, result) << "Failed to unwrap redBufferHandle";
mcasas 2016/12/06 00:04:24 nit: s/redBufferHandle/SharedBuffer/ ?
xianglu 2016/12/08 01:20:53 Done.
63 if (!memory_size || memory_size != num_bytes.ValueOrDie()) {
64 DLOG(ERROR) << "Invalid image size";
65 callback.Run(std::move(faces));
66 return;
67 }
68
69 std::unique_ptr<base::SharedMemory> shared_memory(
70 new base::SharedMemory(memory_handle, true /* read_only */));
71 if (!shared_memory->Map(memory_size)) {
72 DLOG(ERROR) << "Failed to map bytes from shared memory";
73 callback.Run(std::move(faces));
74 return;
75 }
76
77 NSData* byte_data = [NSData dataWithBytesNoCopy:shared_memory->memory()
78 length:num_bytes.ValueOrDie()
79 freeWhenDone:NO];
80
81 base::ScopedCFTypeRef<CGColorSpaceRef> colorspace(
82 CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
83
84 // CIImage will return nil when RGBA8 is not supported in a certain sion.
85 base::scoped_nsobject<CIImage> ciimage([[CIImage alloc]
mcasas 2016/12/06 00:04:23 s/ciimage/ci_image/
xianglu 2016/12/08 01:20:53 Done.
86 initWithBitmapData:byte_data
87 bytesPerRow:width * 4
88 size:CGSizeMake(width, height)
89 format:kCIFormatRGBA8
90 colorSpace:colorspace]);
91 if (!ciimage) {
92 DLOG(ERROR) << "Failed to create CIImage";
93 callback.Run(std::move(faces));
94 return;
95 }
96
97 NSArray* const features = [detector_ featuresInImage:ciimage];
98
99 for (CIFaceFeature* const f in features) {
100 // In the default Core Graphics coordinate space, the origin is located
101 // in the lower-left corner, and thus |ciimage| is flipped vertically.
102 // We need to adjust |y| coordinate of bounding box before sending it .
103 gfx::RectF boundingbox(f.bounds.origin.x,
104 height - f.bounds.origin.y - f.bounds.size.height,
105 f.bounds.size.width, f.bounds.size.height);
106 faces->bounding_boxes.push_back(boundingbox);
107 }
108 callback.Run(std::move(faces));
109 }
110
111 } // namespace shape_detection
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698