Skip to content

Commit bf01875

Browse files
authored
[camera_windows] Support camera on windows desktop platform (flutter#4641)
This PR adds a Windows Desktop implementation of [camera plugin](https://pub.dev/packages/camera) using Media Foundation and CaptureEngine interface. The implementation supports multiple cameras, video preview, and capturing photos and videos. Works with camera plugin and [camera example](https://pub.dev/packages/camera/example). The current implementation uses FlutterDesktopPixelBuffer, but could be switched to use shared textures or Platform views after those are supported. Unit tests are partially done; for the CaptureControllerImpl class all falilure code paths are not yet covered. Still missing some features, like exposure and focus controls. These can be done later with interfaces IAMCameraControl and IAMVideoProcAmp, Resolves flutter#41709: [camera] Add Windows support
1 parent dbbd21f commit bf01875

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+9891
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.DS_Store
2+
.dart_tool/
3+
4+
.packages
5+
.pub/
6+
7+
build/
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: 18116933e77adc82f80866c928266a5b4f1ed645
8+
channel: stable
9+
10+
project_type: plugin
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Below is a list of people and organizations that have contributed
2+
# to the Flutter project. Names should be added to the list like so:
3+
#
4+
# Name/Organization <email address>
5+
6+
Google Inc.
7+
Joonas Kerttula <[email protected]>
8+
Codemate Ltd.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 0.1.0
2+
3+
* Initial release
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Copyright 2013 The Flutter Authors. All rights reserved.
2+
3+
Redistribution and use in source and binary forms, with or without modification,
4+
are permitted provided that the following conditions are met:
5+
6+
* Redistributions of source code must retain the above copyright
7+
notice, this list of conditions and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above
9+
copyright notice, this list of conditions and the following
10+
disclaimer in the documentation and/or other materials provided
11+
with the distribution.
12+
* Neither the name of Google Inc. nor the names of its
13+
contributors may be used to endorse or promote products derived
14+
from this software without specific prior written permission.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Camera Windows Plugin
2+
3+
The Windows implementation of [`camera`][camera].
4+
5+
*Note*: This plugin is under development.
6+
See [missing implementations and limitations](#missing-features-on-the-windows-platform).
7+
8+
## Usage
9+
10+
### Depend on the package
11+
12+
This package is not an [endorsed][endorsed-federated-plugin]
13+
implementation of the [`camera`][camera] plugin, so you'll need to
14+
[add it explicitly][install].
15+
16+
## Missing features on the Windows platform
17+
18+
### Device orientation
19+
20+
Device orientation detection
21+
is not yet implemented: [issue #97540][device-orientation-issue].
22+
23+
### Pause and Resume video recording
24+
25+
Pausing and resuming the video recording
26+
is not supported due to Windows API limitations.
27+
28+
### Exposure mode, point and offset
29+
30+
Support for explosure mode and offset
31+
is not yet implemented: [issue #97537][camera-control-issue].
32+
33+
Exposure points are not supported due to
34+
limitations of the Windows API.
35+
36+
### Focus mode and point
37+
38+
Support for explosure mode and offset
39+
is not yet implemented: [issue #97537][camera-control-issue].
40+
41+
### Flash mode
42+
43+
Support for flash mode is not yet implemented: [issue #97537][camera-control-issue].
44+
45+
Focus points are not supported due to
46+
current limitations of the Windows API.
47+
48+
### Streaming of frames
49+
50+
Support for image streaming is not yet implemented: [issue #97542][image-streams-issue].
51+
52+
## Error handling
53+
54+
Camera errors can be listened using the platform's `onCameraError` method.
55+
56+
Listening to errors is important, and in certain situations,
57+
disposing of the camera is the only way to reset the situation.
58+
59+
<!-- Links -->
60+
61+
[camera]: https://pub.dev/packages/camera
62+
[endorsed-federated-plugin]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin
63+
[install]: https://pub.dev/packages/camera_windows/install
64+
[camera-control-issue]: https://github.com/flutter/flutter/issues/97537
65+
[device-orientation-issue]: https://github.com/flutter/flutter/issues/97540
66+
[image-streams-issue]: https://github.com/flutter/flutter/issues/97542
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Miscellaneous
2+
*.class
3+
*.log
4+
*.pyc
5+
*.swp
6+
.DS_Store
7+
.atom/
8+
.buildlog/
9+
.history
10+
.svn/
11+
12+
# IntelliJ related
13+
*.iml
14+
*.ipr
15+
*.iws
16+
.idea/
17+
18+
# The .vscode folder contains launch configuration and tasks you configure in
19+
# VS Code which you may wish to be included in version control, so this line
20+
# is commented out by default.
21+
#.vscode/
22+
23+
# Flutter/Dart/Pub related
24+
**/doc/api/
25+
**/ios/Flutter/.last_build_id
26+
.dart_tool/
27+
.flutter-plugins
28+
.flutter-plugins-dependencies
29+
.packages
30+
.pub-cache/
31+
.pub/
32+
/build/
33+
34+
# Web related
35+
lib/generated_plugin_registrant.dart
36+
37+
# Symbolication related
38+
app.*.symbols
39+
40+
# Obfuscation related
41+
app.*.map.json
42+
43+
# Android Studio will place build artifacts here
44+
/android/app/debug
45+
/android/app/profile
46+
/android/app/release
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: 18116933e77adc82f80866c928266a5b4f1ed645
8+
channel: stable
9+
10+
project_type: app
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# camera_windows_example
2+
3+
Demonstrates how to use the camera_windows plugin.
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2013 The Flutter 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+
import 'dart:async';
6+
import 'package:async/async.dart';
7+
import 'package:camera_platform_interface/camera_platform_interface.dart';
8+
import 'package:flutter/services.dart';
9+
import 'package:flutter_test/flutter_test.dart';
10+
import 'package:integration_test/integration_test.dart';
11+
12+
// Note that these integration tests do not currently cover
13+
// most features and code paths, as they can only be tested if
14+
// one or more cameras are available in the test environment.
15+
// Native unit tests with better coverage are available at
16+
// the native part of the plugin implementation.
17+
18+
void main() {
19+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
20+
21+
group('initializeCamera', () {
22+
testWidgets('throws exception if camera is not created',
23+
(WidgetTester _) async {
24+
final CameraPlatform camera = CameraPlatform.instance;
25+
26+
expect(() async => await camera.initializeCamera(1234),
27+
throwsA(isA<CameraException>()));
28+
});
29+
});
30+
31+
group('takePicture', () {
32+
testWidgets('throws exception if camera is not created',
33+
(WidgetTester _) async {
34+
final CameraPlatform camera = CameraPlatform.instance;
35+
36+
expect(() async => await camera.takePicture(1234),
37+
throwsA(isA<PlatformException>()));
38+
});
39+
});
40+
41+
group('startVideoRecording', () {
42+
testWidgets('throws exception if camera is not created',
43+
(WidgetTester _) async {
44+
final CameraPlatform camera = CameraPlatform.instance;
45+
46+
expect(() async => await camera.startVideoRecording(1234),
47+
throwsA(isA<PlatformException>()));
48+
});
49+
});
50+
51+
group('stopVideoRecording', () {
52+
testWidgets('throws exception if camera is not created',
53+
(WidgetTester _) async {
54+
final CameraPlatform camera = CameraPlatform.instance;
55+
56+
expect(() async => await camera.stopVideoRecording(1234),
57+
throwsA(isA<PlatformException>()));
58+
});
59+
});
60+
61+
group('pausePreview', () {
62+
testWidgets('throws exception if camera is not created',
63+
(WidgetTester _) async {
64+
final CameraPlatform camera = CameraPlatform.instance;
65+
66+
expect(() async => await camera.pausePreview(1234),
67+
throwsA(isA<PlatformException>()));
68+
});
69+
});
70+
71+
group('resumePreview', () {
72+
testWidgets('throws exception if camera is not created',
73+
(WidgetTester _) async {
74+
final CameraPlatform camera = CameraPlatform.instance;
75+
76+
expect(() async => await camera.resumePreview(1234),
77+
throwsA(isA<PlatformException>()));
78+
});
79+
});
80+
81+
group('onDeviceOrientationChanged', () {
82+
testWidgets('emits the initial DeviceOrientationChangedEvent',
83+
(WidgetTester _) async {
84+
final Stream<DeviceOrientationChangedEvent> eventStream =
85+
CameraPlatform.instance.onDeviceOrientationChanged();
86+
87+
final StreamQueue<DeviceOrientationChangedEvent> streamQueue =
88+
StreamQueue<DeviceOrientationChangedEvent>(eventStream);
89+
90+
expect(
91+
await streamQueue.next,
92+
equals(
93+
const DeviceOrientationChangedEvent(
94+
DeviceOrientation.landscapeRight,
95+
),
96+
),
97+
);
98+
});
99+
});
100+
}

0 commit comments

Comments
 (0)