[camera][draft] Add camera plugin (#29)
Added the first draft version, but there are still a lot of unimplemented features.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
flutter/
|
||||
@@ -0,0 +1,47 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
set(PROJECT_NAME "camera_elinux")
|
||||
project(${PROJECT_NAME} LANGUAGES CXX)
|
||||
|
||||
# This value is used when generating builds using this plugin, so it must
|
||||
# not be changed
|
||||
set(PLUGIN_NAME "camera_elinux_plugin")
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
||||
pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0)
|
||||
|
||||
add_library(${PLUGIN_NAME} SHARED
|
||||
"camera_elinux_plugin.cc"
|
||||
"gst_camera.cc"
|
||||
"types/exposure_mode.cc"
|
||||
"types/focus_mode.cc"
|
||||
"types/orientation.cc"
|
||||
"method_channel/method_channel_camera.cc"
|
||||
"method_channel/method_channel_device.cc"
|
||||
)
|
||||
apply_standard_settings(${PLUGIN_NAME})
|
||||
set_target_properties(${PLUGIN_NAME} PROPERTIES
|
||||
CXX_VISIBILITY_PRESET hidden)
|
||||
target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
|
||||
target_include_directories(${PLUGIN_NAME} INTERFACE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin)
|
||||
|
||||
target_include_directories(${PLUGIN_NAME}
|
||||
PRIVATE
|
||||
"./"
|
||||
${GLIB_INCLUDE_DIRS}
|
||||
${GSTREAMER_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(${PLUGIN_NAME}
|
||||
PRIVATE
|
||||
${GLIB_LIBRARIES}
|
||||
${GSTREAMER_LIBRARIES}
|
||||
)
|
||||
|
||||
# List of absolute paths to libraries that should be bundled with the plugin
|
||||
set(camera_elinux_bundled_libraries
|
||||
""
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -0,0 +1,340 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "include/camera_elinux/camera_elinux_plugin.h"
|
||||
|
||||
#include <flutter/method_channel.h>
|
||||
#include <flutter/plugin_registrar.h>
|
||||
#include <flutter/standard_method_codec.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "camera_stream_handler_impl.h"
|
||||
#include "events/camera_initialized_event.h"
|
||||
#include "gst_camera.h"
|
||||
#include "messages/messages.h"
|
||||
#include "method_channel/method_channel_camera.h"
|
||||
#include "method_channel/method_channel_device.h"
|
||||
|
||||
namespace {
|
||||
constexpr char kCameraChannelName[] = "plugins.flutter.io/camera";
|
||||
|
||||
constexpr char kCameraChannelApiAvailableCameras[] = "availableCameras";
|
||||
constexpr char kCameraChannelApiCreate[] = "create";
|
||||
constexpr char kCameraChannelApiInitialize[] = "initialize";
|
||||
constexpr char kCameraChannelApiTakePicture[] = "takePicture";
|
||||
constexpr char kCameraChannelApiPrepareForVideoRecording[] =
|
||||
"prepareForVideoRecording";
|
||||
constexpr char kCameraChannelApiStartVideoRecording[] = "startVideoRecording";
|
||||
constexpr char kCameraChannelApiStopVideoRecording[] = "stopVideoRecording";
|
||||
constexpr char kCameraChannelApiPauseVideoRecording[] = "pauseVideoRecording";
|
||||
constexpr char kCameraChannelApiResumeVideoRecording[] = "resumeVideoRecording";
|
||||
constexpr char kCameraChannelApiSetFlashMode[] = "setFlashMode";
|
||||
constexpr char kCameraChannelApiSetExposureMode[] = "setExposureMode";
|
||||
constexpr char kCameraChannelApiSetExposurePoint[] = "setExposurePoint";
|
||||
constexpr char kCameraChannelApiGetMinExposureOffset[] = "getMinExposureOffset";
|
||||
constexpr char kCameraChannelApiGetMaxExposureOffset[] = "getMaxExposureOffset";
|
||||
constexpr char kCameraChannelApiGetExposureOffsetStepSize[] =
|
||||
"getExposureOffsetStepSize";
|
||||
constexpr char kCameraChannelApiSetExposureOffset[] = "setExposureOffset";
|
||||
constexpr char kCameraChannelApiSetFocusMode[] = "setFocusMode";
|
||||
constexpr char kCameraChannelApiSetFocusPoint[] = "setFocusPoint";
|
||||
constexpr char kCameraChannelApiStartImageStream[] = "startImageStream";
|
||||
constexpr char kCameraChannelApiStopImageStream[] = "stopImageStream";
|
||||
constexpr char kCameraChannelApiGetMaxZoomLevel[] = "getMaxZoomLevel";
|
||||
constexpr char kCameraChannelApiGetMinZoomLevel[] = "getMinZoomLevel";
|
||||
constexpr char kCameraChannelApiSetZoomLevel[] = "setZoomLevel";
|
||||
constexpr char kCameraChannelApiLockCaptureOrientation[] =
|
||||
"lockCaptureOrientation";
|
||||
constexpr char kCameraChannelApiUnlockCaptureOrientation[] =
|
||||
"unlockCaptureOrientation";
|
||||
constexpr char kCameraChannelApiDispose[] = "dispose";
|
||||
|
||||
class CameraPlugin : public flutter::Plugin {
|
||||
public:
|
||||
static void RegisterWithRegistrar(flutter::PluginRegistrar* registrar);
|
||||
|
||||
CameraPlugin(flutter::PluginRegistrar* plugin_registrar,
|
||||
flutter::TextureRegistrar* texture_registrar)
|
||||
: plugin_registrar_(plugin_registrar),
|
||||
texture_registrar_(texture_registrar) {
|
||||
GstCamera::GstLibraryLoad();
|
||||
}
|
||||
virtual ~CameraPlugin() {
|
||||
if (camera_) {
|
||||
camera_->Stop();
|
||||
camera_ = nullptr;
|
||||
}
|
||||
GstCamera::GstLibraryUnload();
|
||||
}
|
||||
|
||||
private:
|
||||
void HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
|
||||
void HandleAvailableCamerasCall(
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
void HandleCreateCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
void HandleInitializeCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
void HandleGetMaxZoomLevelCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
void HandleGetMinZoomLevelCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
void HandleSetZoomLevelCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
void HandleLockCaptureOrientationCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
void HandleDisposeCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
|
||||
flutter::PluginRegistrar* plugin_registrar_;
|
||||
flutter::TextureRegistrar* texture_registrar_;
|
||||
|
||||
std::unique_ptr<FlutterDesktopPixelBuffer> buffer_;
|
||||
std::unique_ptr<flutter::TextureVariant> texture_;
|
||||
std::unique_ptr<GstCamera> camera_ = nullptr;
|
||||
int64_t texture_id_;
|
||||
std::unique_ptr<MethodChannelCamera> method_channel_camera_;
|
||||
std::unique_ptr<MethodChannelDevice> method_channel_device_;
|
||||
};
|
||||
|
||||
// static
|
||||
void CameraPlugin::RegisterWithRegistrar(flutter::PluginRegistrar* registrar) {
|
||||
auto plugin =
|
||||
std::make_unique<CameraPlugin>(registrar, registrar->texture_registrar());
|
||||
auto channel =
|
||||
std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
|
||||
registrar->messenger(), kCameraChannelName,
|
||||
&flutter::StandardMethodCodec::GetInstance());
|
||||
|
||||
channel->SetMethodCallHandler(
|
||||
[plugin_pointer = plugin.get()](const auto& call, auto result) {
|
||||
plugin_pointer->HandleMethodCall(call, std::move(result));
|
||||
});
|
||||
|
||||
registrar->AddPlugin(std::move(plugin));
|
||||
}
|
||||
|
||||
void CameraPlugin::HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
const std::string& method_name = method_call.method_name();
|
||||
|
||||
if (!method_name.compare(kCameraChannelApiAvailableCameras)) {
|
||||
HandleAvailableCamerasCall(std::move(result));
|
||||
} else if (!method_name.compare(kCameraChannelApiCreate)) {
|
||||
HandleCreateCall(method_call.arguments(), std::move(result));
|
||||
} else if (!method_name.compare(kCameraChannelApiInitialize)) {
|
||||
HandleInitializeCall(method_call.arguments(), std::move(result));
|
||||
} else if (!method_name.compare(kCameraChannelApiTakePicture)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiPrepareForVideoRecording)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiStartVideoRecording)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiStopVideoRecording)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiPauseVideoRecording)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiResumeVideoRecording)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiSetFlashMode)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiSetExposureMode)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiSetExposurePoint)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiGetMinExposureOffset)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiGetMaxExposureOffset)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiGetExposureOffsetStepSize)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiSetExposureOffset)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiSetFocusMode)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiSetFocusPoint)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiStartImageStream)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiStopImageStream)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiGetMaxZoomLevel)) {
|
||||
HandleGetMaxZoomLevelCall(method_call.arguments(), std::move(result));
|
||||
} else if (!method_name.compare(kCameraChannelApiGetMinZoomLevel)) {
|
||||
HandleGetMinZoomLevelCall(method_call.arguments(), std::move(result));
|
||||
} else if (!method_name.compare(kCameraChannelApiSetZoomLevel)) {
|
||||
HandleSetZoomLevelCall(method_call.arguments(), std::move(result));
|
||||
} else if (!method_name.compare(kCameraChannelApiLockCaptureOrientation)) {
|
||||
HandleLockCaptureOrientationCall(method_call.arguments(),
|
||||
std::move(result));
|
||||
} else if (!method_name.compare(kCameraChannelApiUnlockCaptureOrientation)) {
|
||||
result->NotImplemented();
|
||||
} else if (!method_name.compare(kCameraChannelApiDispose)) {
|
||||
HandleDisposeCall(method_call.arguments(), std::move(result));
|
||||
} else {
|
||||
result->NotImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
void CameraPlugin::HandleAvailableCamerasCall(
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
flutter::EncodableList cameras;
|
||||
|
||||
// TODO: add multi camera support.
|
||||
for (int i = 0; i < 1; i++) {
|
||||
AvailableCamerasMessage camera;
|
||||
camera.SetName("camera" + std::to_string(i));
|
||||
camera.SetSensorOrientation(0);
|
||||
camera.SetLensFacing("back");
|
||||
cameras.push_back(camera.ToMap());
|
||||
}
|
||||
|
||||
result->Success(flutter::EncodableValue(cameras));
|
||||
}
|
||||
|
||||
void CameraPlugin::HandleCreateCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
// auto meta = CreateMessage::FromMap(message);
|
||||
|
||||
buffer_ = std::make_unique<FlutterDesktopPixelBuffer>();
|
||||
texture_ =
|
||||
std::make_unique<flutter::TextureVariant>(flutter::PixelBufferTexture(
|
||||
[host = this](size_t width,
|
||||
size_t height) -> const FlutterDesktopPixelBuffer* {
|
||||
host->buffer_->width = host->camera_->GetPreviewWidth();
|
||||
host->buffer_->height = host->camera_->GetPreviewHeight();
|
||||
host->buffer_->buffer = host->camera_->GetPreviewFrameBuffer();
|
||||
return host->buffer_.get();
|
||||
}));
|
||||
auto texture_id = texture_registrar_->RegisterTexture(texture_.get());
|
||||
auto stream_handler = std::make_unique<CameraStreamHandlerImpl>(
|
||||
// OnNotifyInitialized
|
||||
[]() {},
|
||||
// OnNotifyFrameDecoded
|
||||
[texture_id, host = this]() {
|
||||
host->texture_registrar_->MarkTextureFrameAvailable(texture_id);
|
||||
},
|
||||
// OnNotifyCompleted
|
||||
[]() {});
|
||||
|
||||
camera_ = std::make_unique<GstCamera>(std::move(stream_handler));
|
||||
texture_id_ = texture_id;
|
||||
|
||||
flutter::EncodableMap reply;
|
||||
reply[flutter::EncodableValue("cameraId")] =
|
||||
flutter::EncodableValue(texture_id);
|
||||
|
||||
result->Success(flutter::EncodableValue(reply));
|
||||
}
|
||||
|
||||
void CameraPlugin::HandleInitializeCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
camera_->Play();
|
||||
double preview_width = camera_->GetPreviewWidth();
|
||||
double preview_height = camera_->GetPreviewHeight();
|
||||
|
||||
{
|
||||
method_channel_camera_ =
|
||||
std::make_unique<MethodChannelCamera>(plugin_registrar_, texture_id_);
|
||||
|
||||
CameraInitializedEvent message;
|
||||
message.SetPreviewWidth(preview_width);
|
||||
message.SetPreviewHeight(preview_height);
|
||||
message.SetFocusMode(FocusMode::kAuto);
|
||||
message.SetExposureMode(ExposureMode::kAuto);
|
||||
message.SetFocusPointSupported(false);
|
||||
message.SetExposurePointSupported(false);
|
||||
|
||||
method_channel_camera_->SendInitializedEvent(message);
|
||||
}
|
||||
|
||||
{
|
||||
method_channel_device_ =
|
||||
std::make_unique<MethodChannelDevice>(plugin_registrar_);
|
||||
auto orientation = DeviceOrientation::kLandscapeRight;
|
||||
|
||||
method_channel_device_->SendDeviceOrientationChangeEvent(orientation);
|
||||
}
|
||||
result->Success();
|
||||
}
|
||||
|
||||
void CameraPlugin::HandleGetMaxZoomLevelCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
if (!camera_) {
|
||||
result->Error("Not found an active camera",
|
||||
"Check for creating a camera device");
|
||||
return;
|
||||
}
|
||||
result->Success(flutter::EncodableValue(camera_->GetMaxZoomLevel()));
|
||||
}
|
||||
|
||||
void CameraPlugin::HandleGetMinZoomLevelCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
if (!camera_) {
|
||||
result->Error("Not found an active camera",
|
||||
"Check for creating a camera device");
|
||||
return;
|
||||
}
|
||||
result->Success(flutter::EncodableValue(camera_->GetMinZoomLevel()));
|
||||
}
|
||||
|
||||
void CameraPlugin::HandleSetZoomLevelCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
if (!camera_) {
|
||||
result->Error("Not found an active camera",
|
||||
"Check for creating a camera device");
|
||||
return;
|
||||
}
|
||||
|
||||
auto meta = ZoomLevelMessage::FromMap(*message);
|
||||
if (camera_->SetZoomLevel(meta.GetZoom())) {
|
||||
result->Success();
|
||||
} else {
|
||||
result->Error("Failed to change the zoom level", "Check the zoom level");
|
||||
}
|
||||
}
|
||||
|
||||
void CameraPlugin::HandleLockCaptureOrientationCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
result->NotImplemented();
|
||||
}
|
||||
|
||||
void CameraPlugin::HandleDisposeCall(
|
||||
const flutter::EncodableValue* message,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
// TODO: add multi camera support.
|
||||
if (camera_) {
|
||||
camera_->Stop();
|
||||
camera_ = nullptr;
|
||||
texture_registrar_->UnregisterTexture(texture_id_);
|
||||
}
|
||||
result->Success();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void CameraElinuxPluginRegisterWithRegistrar(
|
||||
FlutterDesktopPluginRegistrarRef registrar) {
|
||||
CameraPlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrarManager::GetInstance()
|
||||
->GetRegistrar<flutter::PluginRegistrar>(registrar));
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_STREAM_HANDLER_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_STREAM_HANDLER_H_
|
||||
|
||||
class CameraStreamHandler {
|
||||
public:
|
||||
CameraStreamHandler() = default;
|
||||
virtual ~CameraStreamHandler() = default;
|
||||
|
||||
// Prevent copying.
|
||||
CameraStreamHandler(CameraStreamHandler const&) = delete;
|
||||
CameraStreamHandler& operator=(CameraStreamHandler const&) = delete;
|
||||
|
||||
// Notifies the completion of initializing the video player.
|
||||
void OnNotifyInitialized() { OnNotifyInitializedInternal(); }
|
||||
|
||||
// Notifies the completion of decoding a video frame.
|
||||
void OnNotifyFrameDecoded() { OnNotifyFrameDecodedInternal(); }
|
||||
|
||||
// Notifies the completion of playing a video.
|
||||
void OnNotifyCompleted() { OnNotifyCompletedInternal(); }
|
||||
|
||||
protected:
|
||||
virtual void OnNotifyInitializedInternal() = 0;
|
||||
virtual void OnNotifyFrameDecodedInternal() = 0;
|
||||
virtual void OnNotifyCompletedInternal() = 0;
|
||||
};
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_STREAM_HANDLER_H_
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_STREAM_HANDLER_IMPL_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_STREAM_HANDLER_IMPL_H_
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "camera_stream_handler.h"
|
||||
|
||||
class CameraStreamHandlerImpl : public CameraStreamHandler {
|
||||
public:
|
||||
using OnNotifyInitialized = std::function<void()>;
|
||||
using OnNotifyFrameDecoded = std::function<void()>;
|
||||
using OnNotifyCompleted = std::function<void()>;
|
||||
|
||||
CameraStreamHandlerImpl(OnNotifyInitialized on_notify_initialized,
|
||||
OnNotifyFrameDecoded on_notify_frame_decoded,
|
||||
OnNotifyCompleted on_notify_completed)
|
||||
: on_notify_initialized_(on_notify_initialized),
|
||||
on_notify_frame_decoded_(on_notify_frame_decoded),
|
||||
on_notify_completed_(on_notify_completed) {}
|
||||
virtual ~CameraStreamHandlerImpl() = default;
|
||||
|
||||
// Prevent copying.
|
||||
CameraStreamHandlerImpl(CameraStreamHandlerImpl const&) = delete;
|
||||
CameraStreamHandlerImpl& operator=(CameraStreamHandlerImpl const&) = delete;
|
||||
|
||||
protected:
|
||||
// |CameraStreamHandler|
|
||||
void OnNotifyInitializedInternal() {
|
||||
if (on_notify_initialized_) {
|
||||
on_notify_initialized_();
|
||||
}
|
||||
}
|
||||
|
||||
// |CameraStreamHandler|
|
||||
void OnNotifyFrameDecodedInternal() {
|
||||
if (on_notify_frame_decoded_) {
|
||||
on_notify_frame_decoded_();
|
||||
}
|
||||
}
|
||||
|
||||
// |CameraStreamHandler|
|
||||
void OnNotifyCompletedInternal() {
|
||||
if (on_notify_completed_) {
|
||||
on_notify_completed_();
|
||||
}
|
||||
}
|
||||
|
||||
OnNotifyInitialized on_notify_initialized_;
|
||||
OnNotifyFrameDecoded on_notify_frame_decoded_;
|
||||
OnNotifyCompleted on_notify_completed_;
|
||||
};
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_STREAM_HANDLER_IMPL_H_
|
||||
@@ -0,0 +1,128 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_EVENT_CAMERA_INITIALIZED_EVENT_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_EVENT_CAMERA_INITIALIZED_EVENT_H_
|
||||
|
||||
#include <flutter/binary_messenger.h>
|
||||
#include <flutter/encodable_value.h>
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include "types/exposure_mode.h"
|
||||
#include "types/focus_mode.h"
|
||||
|
||||
// See:
|
||||
// flutter/plugins/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart
|
||||
class CameraInitializedEvent {
|
||||
public:
|
||||
CameraInitializedEvent() = default;
|
||||
~CameraInitializedEvent() = default;
|
||||
|
||||
// Prevent copying.
|
||||
CameraInitializedEvent(CameraInitializedEvent const&) = default;
|
||||
CameraInitializedEvent& operator=(CameraInitializedEvent const&) = default;
|
||||
|
||||
void SetPreviewWidth(const double& width) { preview_width_ = width; }
|
||||
double GetPreviewWidth() const { return preview_width_; }
|
||||
|
||||
void SetPreviewHeight(const double& height) { preview_height_ = height; }
|
||||
double GetPreviewHeight() const { return preview_height_; }
|
||||
|
||||
void SetFocusMode(const FocusMode& focus_mode) { focus_mode_ = focus_mode; }
|
||||
FocusMode GetFocusMode() const { return focus_mode_; }
|
||||
|
||||
void SetExposureMode(const ExposureMode& exposure_mode) {
|
||||
exposure_mode_ = exposure_mode;
|
||||
}
|
||||
ExposureMode GetExposureMode() const { return exposure_mode_; }
|
||||
|
||||
void SetFocusPointSupported(const bool& supported) {
|
||||
focus_point_supported_ = supported;
|
||||
}
|
||||
bool GetFocusPointSupported() const { return focus_point_supported_; }
|
||||
|
||||
void SetExposurePointSupported(const bool& supported) {
|
||||
exposure_point_supported_ = supported;
|
||||
}
|
||||
bool GetExposurePointSupported() const { return exposure_point_supported_; }
|
||||
|
||||
flutter::EncodableValue ToMap() {
|
||||
flutter::EncodableMap map = {
|
||||
{flutter::EncodableValue("previewWidth"),
|
||||
flutter::EncodableValue(preview_width_)},
|
||||
{flutter::EncodableValue("previewHeight"),
|
||||
flutter::EncodableValue(preview_height_)},
|
||||
{flutter::EncodableValue("focusMode"),
|
||||
flutter::EncodableValue(SerializeFocusMode(focus_mode_))},
|
||||
{flutter::EncodableValue("exposureMode"),
|
||||
flutter::EncodableValue(SerializeExposureMode(exposure_mode_))},
|
||||
{flutter::EncodableValue("focusPointSupported"),
|
||||
flutter::EncodableValue(focus_point_supported_)},
|
||||
{flutter::EncodableValue("exposurePointSupported"),
|
||||
flutter::EncodableValue(exposure_point_supported_)},
|
||||
};
|
||||
return flutter::EncodableValue(map);
|
||||
}
|
||||
|
||||
static CameraInitializedEvent FromMap(const flutter::EncodableValue& value) {
|
||||
CameraInitializedEvent message;
|
||||
if (std::holds_alternative<flutter::EncodableMap>(value)) {
|
||||
auto map = std::get<flutter::EncodableMap>(value);
|
||||
|
||||
flutter::EncodableValue& preview_width =
|
||||
map[flutter::EncodableValue("previewWidth")];
|
||||
if (std::holds_alternative<double>(preview_width)) {
|
||||
message.SetPreviewWidth(std::get<double>(preview_width));
|
||||
}
|
||||
|
||||
flutter::EncodableValue& preview_height =
|
||||
map[flutter::EncodableValue("previewHeight")];
|
||||
if (std::holds_alternative<double>(preview_height)) {
|
||||
message.SetPreviewHeight(std::get<double>(preview_height));
|
||||
}
|
||||
|
||||
flutter::EncodableValue& focus_mode =
|
||||
map[flutter::EncodableValue("focusMode")];
|
||||
if (std::holds_alternative<std::string>(focus_mode)) {
|
||||
message.SetFocusMode(
|
||||
DeserializeFocusMode(std::get<std::string>(focus_mode)));
|
||||
}
|
||||
|
||||
flutter::EncodableValue& exposure_mode =
|
||||
map[flutter::EncodableValue("exposureMode")];
|
||||
if (std::holds_alternative<std::string>(exposure_mode)) {
|
||||
message.SetExposureMode(
|
||||
DeserializeExposureMode(std::get<std::string>(exposure_mode)));
|
||||
}
|
||||
|
||||
flutter::EncodableValue& focus_point_supported =
|
||||
map[flutter::EncodableValue("focusPointSupported")];
|
||||
if (std::holds_alternative<bool>(focus_point_supported)) {
|
||||
message.SetFocusPointSupported(std::get<bool>(focus_point_supported));
|
||||
}
|
||||
|
||||
flutter::EncodableValue& exposure_point_supported =
|
||||
map[flutter::EncodableValue("exposurePointSupported")];
|
||||
if (std::holds_alternative<bool>(exposure_point_supported)) {
|
||||
message.SetExposurePointSupported(
|
||||
std::get<bool>(exposure_point_supported));
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
private:
|
||||
double preview_width_;
|
||||
double preview_height_;
|
||||
FocusMode focus_mode_;
|
||||
ExposureMode exposure_mode_;
|
||||
bool focus_point_supported_;
|
||||
bool exposure_point_supported_;
|
||||
};
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_EVENT_CAMERA_INITIALIZED_EVENT_H_
|
||||
@@ -0,0 +1,309 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "gst_camera.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
GstCamera::GstCamera(std::unique_ptr<CameraStreamHandler> handler)
|
||||
: stream_handler_(std::move(handler)) {
|
||||
gst_.pipeline = nullptr;
|
||||
gst_.camerabin = nullptr;
|
||||
gst_.video_convert = nullptr;
|
||||
gst_.video_sink = nullptr;
|
||||
gst_.output = nullptr;
|
||||
gst_.bus = nullptr;
|
||||
gst_.buffer = nullptr;
|
||||
|
||||
if (!CreatePipeline()) {
|
||||
std::cerr << "Failed to create a pipeline" << std::endl;
|
||||
DestroyPipeline();
|
||||
return;
|
||||
}
|
||||
|
||||
// Prerolls before getting information from the pipeline.
|
||||
Preroll();
|
||||
|
||||
GetZoomMaxMinSize(max_zoom_level_, min_zoom_level_);
|
||||
}
|
||||
|
||||
GstCamera::~GstCamera() {
|
||||
Stop();
|
||||
DestroyPipeline();
|
||||
}
|
||||
|
||||
// static
|
||||
void GstCamera::GstLibraryLoad() { gst_init(NULL, NULL); }
|
||||
|
||||
// static
|
||||
void GstCamera::GstLibraryUnload() { gst_deinit(); }
|
||||
|
||||
bool GstCamera::Play() {
|
||||
auto result = gst_element_set_state(gst_.pipeline, GST_STATE_PLAYING);
|
||||
if (result == GST_STATE_CHANGE_FAILURE) {
|
||||
std::cerr << "Failed to change the state to PLAYING" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Waits until the state becomes GST_STATE_PLAYING.
|
||||
if (result == GST_STATE_CHANGE_ASYNC) {
|
||||
GstState state;
|
||||
result =
|
||||
gst_element_get_state(gst_.pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
|
||||
if (result == GST_STATE_CHANGE_FAILURE) {
|
||||
std::cerr << "Failed to get the current state" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GstCamera::Pause() {
|
||||
if (gst_element_set_state(gst_.pipeline, GST_STATE_PAUSED) ==
|
||||
GST_STATE_CHANGE_FAILURE) {
|
||||
std::cerr << "Failed to change the state to PAUSED" << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GstCamera::Stop() {
|
||||
if (gst_element_set_state(gst_.pipeline, GST_STATE_READY) ==
|
||||
GST_STATE_CHANGE_FAILURE) {
|
||||
std::cerr << "Failed to change the state to READY" << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GstCamera::SetZoomLevel(float zoom) {
|
||||
if (zoom_level_ == zoom) {
|
||||
return true;
|
||||
}
|
||||
if (max_zoom_level_ < zoom) {
|
||||
std::cerr << "zoom level(" << zoom << ") is over the max-zoom level("
|
||||
<< max_zoom_level_ << ")" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (min_zoom_level_ > zoom) {
|
||||
std::cerr << "zoom level(" << zoom << ") is under the min-zoom level("
|
||||
<< min_zoom_level_ << ")" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
g_object_set(gst_.camerabin, "zoom", zoom, NULL);
|
||||
zoom_level_ = zoom;
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8_t* GstCamera::GetPreviewFrameBuffer() {
|
||||
std::shared_lock<std::shared_mutex> lock(mutex_buffer_);
|
||||
if (!gst_.buffer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const uint32_t pixel_bytes = width_ * height_ * 4;
|
||||
gst_buffer_extract(gst_.buffer, 0, pixels_.get(), pixel_bytes);
|
||||
return reinterpret_cast<const uint8_t*>(pixels_.get());
|
||||
}
|
||||
|
||||
// Creats a camra pipeline using camerabin.
|
||||
// $ gst-launch-1.0 camerabin viewfinder-sink="videoconvert !
|
||||
// video/x-raw,format=RGBA ! fakesink"
|
||||
bool GstCamera::CreatePipeline() {
|
||||
gst_.pipeline = gst_pipeline_new("pipeline");
|
||||
if (!gst_.pipeline) {
|
||||
std::cerr << "Failed to create a pipeline" << std::endl;
|
||||
return false;
|
||||
}
|
||||
gst_.camerabin = gst_element_factory_make("camerabin", "camerabin");
|
||||
if (!gst_.camerabin) {
|
||||
std::cerr << "Failed to create a source" << std::endl;
|
||||
return false;
|
||||
}
|
||||
gst_.video_convert = gst_element_factory_make("videoconvert", "videoconvert");
|
||||
if (!gst_.video_convert) {
|
||||
std::cerr << "Failed to create a videoconvert" << std::endl;
|
||||
return false;
|
||||
}
|
||||
gst_.video_sink = gst_element_factory_make("fakesink", "videosink");
|
||||
if (!gst_.video_sink) {
|
||||
std::cerr << "Failed to create a videosink" << std::endl;
|
||||
return false;
|
||||
}
|
||||
gst_.output = gst_bin_new("output");
|
||||
if (!gst_.output) {
|
||||
std::cerr << "Failed to create an output" << std::endl;
|
||||
return false;
|
||||
}
|
||||
gst_.bus = gst_pipeline_get_bus(GST_PIPELINE(gst_.pipeline));
|
||||
if (!gst_.bus) {
|
||||
std::cerr << "Failed to create a bus" << std::endl;
|
||||
return false;
|
||||
}
|
||||
gst_bus_set_sync_handler(gst_.bus, (GstBusSyncHandler)HandleGstMessage, this,
|
||||
NULL);
|
||||
|
||||
// Sets properties to fakesink to get the callback of a decoded frame.
|
||||
g_object_set(G_OBJECT(gst_.video_sink), "sync", TRUE, "qos", FALSE, NULL);
|
||||
g_object_set(G_OBJECT(gst_.video_sink), "signal-handoffs", TRUE, NULL);
|
||||
g_signal_connect(G_OBJECT(gst_.video_sink), "handoff",
|
||||
G_CALLBACK(HandoffHandler), this);
|
||||
gst_bin_add_many(GST_BIN(gst_.output), gst_.video_convert, gst_.video_sink,
|
||||
NULL);
|
||||
|
||||
// Adds caps to the converter to convert the color format to RGBA.
|
||||
auto* caps = gst_caps_from_string("video/x-raw,format=RGBA");
|
||||
auto link_ok =
|
||||
gst_element_link_filtered(gst_.video_convert, gst_.video_sink, caps);
|
||||
gst_caps_unref(caps);
|
||||
if (!link_ok) {
|
||||
std::cerr << "Failed to link elements" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* sinkpad = gst_element_get_static_pad(gst_.video_convert, "sink");
|
||||
auto* ghost_sinkpad = gst_ghost_pad_new("sink", sinkpad);
|
||||
gst_pad_set_active(ghost_sinkpad, TRUE);
|
||||
gst_element_add_pad(gst_.output, ghost_sinkpad);
|
||||
|
||||
// Sets properties to camerabin.
|
||||
g_object_set(gst_.camerabin, "viewfinder-sink", gst_.output, NULL);
|
||||
gst_bin_add_many(GST_BIN(gst_.pipeline), gst_.camerabin, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GstCamera::Preroll() {
|
||||
if (!gst_.camerabin) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto result = gst_element_set_state(gst_.pipeline, GST_STATE_PAUSED);
|
||||
if (result == GST_STATE_CHANGE_FAILURE) {
|
||||
std::cerr << "Failed to change the state to PAUSED" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Waits until the state becomes GST_STATE_PAUSED.
|
||||
if (result == GST_STATE_CHANGE_ASYNC) {
|
||||
GstState state;
|
||||
result =
|
||||
gst_element_get_state(gst_.pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
|
||||
if (result == GST_STATE_CHANGE_FAILURE) {
|
||||
std::cerr << "Failed to get the current state" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GstCamera::DestroyPipeline() {
|
||||
if (gst_.video_sink) {
|
||||
g_object_set(G_OBJECT(gst_.video_sink), "signal-handoffs", FALSE, NULL);
|
||||
}
|
||||
|
||||
if (gst_.pipeline) {
|
||||
gst_element_set_state(gst_.pipeline, GST_STATE_NULL);
|
||||
}
|
||||
|
||||
if (gst_.buffer) {
|
||||
gst_buffer_unref(gst_.buffer);
|
||||
gst_.buffer = nullptr;
|
||||
}
|
||||
|
||||
if (gst_.bus) {
|
||||
gst_object_unref(gst_.bus);
|
||||
gst_.bus = nullptr;
|
||||
}
|
||||
|
||||
if (gst_.pipeline) {
|
||||
gst_object_unref(gst_.pipeline);
|
||||
gst_.pipeline = nullptr;
|
||||
}
|
||||
|
||||
if (gst_.camerabin) {
|
||||
gst_.camerabin = nullptr;
|
||||
}
|
||||
|
||||
if (gst_.output) {
|
||||
gst_.output = nullptr;
|
||||
}
|
||||
|
||||
if (gst_.video_sink) {
|
||||
gst_.video_sink = nullptr;
|
||||
}
|
||||
|
||||
if (gst_.video_convert) {
|
||||
gst_.video_convert = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GstCamera::GetZoomMaxMinSize(float& max, float& min) {
|
||||
if (!gst_.pipeline || !gst_.camerabin) {
|
||||
std::cerr << "The pileline hasn't initialized yet.";
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_get(gst_.camerabin, "max-zoom", &max, NULL);
|
||||
min = 1.0;
|
||||
}
|
||||
|
||||
// static
|
||||
void GstCamera::HandoffHandler(GstElement* fakesink, GstBuffer* buf,
|
||||
GstPad* new_pad, gpointer user_data) {
|
||||
auto* self = reinterpret_cast<GstCamera*>(user_data);
|
||||
auto* caps = gst_pad_get_current_caps(new_pad);
|
||||
auto* structure = gst_caps_get_structure(caps, 0);
|
||||
|
||||
int width;
|
||||
int height;
|
||||
gst_structure_get_int(structure, "width", &width);
|
||||
gst_structure_get_int(structure, "height", &height);
|
||||
if (width != self->width_ || height != self->height_) {
|
||||
self->width_ = width;
|
||||
self->height_ = height;
|
||||
self->pixels_.reset(new uint32_t[width * height]);
|
||||
std::cout << "Pixel buffer size: width = " << width
|
||||
<< ", height = " << height << std::endl;
|
||||
}
|
||||
|
||||
std::lock_guard<std::shared_mutex> lock(self->mutex_buffer_);
|
||||
if (self->gst_.buffer) {
|
||||
gst_buffer_unref(self->gst_.buffer);
|
||||
self->gst_.buffer = nullptr;
|
||||
}
|
||||
self->gst_.buffer = gst_buffer_ref(buf);
|
||||
self->stream_handler_->OnNotifyFrameDecoded();
|
||||
}
|
||||
|
||||
// static
|
||||
gboolean GstCamera::HandleGstMessage(GstBus* bus, GstMessage* message,
|
||||
gpointer user_data) {
|
||||
switch (GST_MESSAGE_TYPE(message)) {
|
||||
case GST_MESSAGE_WARNING: {
|
||||
gchar* debug;
|
||||
GError* error;
|
||||
gst_message_parse_warning(message, &error, &debug);
|
||||
g_printerr("WARNING from element %s: %s\n", GST_OBJECT_NAME(message->src),
|
||||
error->message);
|
||||
g_printerr("Warning details: %s\n", debug);
|
||||
g_free(debug);
|
||||
g_error_free(error);
|
||||
break;
|
||||
}
|
||||
case GST_MESSAGE_ERROR: {
|
||||
gchar* debug;
|
||||
GError* error;
|
||||
gst_message_parse_error(message, &error, &debug);
|
||||
g_printerr("ERROR from element %s: %s\n", GST_OBJECT_NAME(message->src),
|
||||
error->message);
|
||||
g_printerr("Error details: %s\n", debug);
|
||||
g_free(debug);
|
||||
g_error_free(error);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_GST_CAMERA_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_GST_CAMERA_H_
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <memory>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
|
||||
#include "camera_stream_handler.h"
|
||||
|
||||
class GstCamera {
|
||||
public:
|
||||
GstCamera(std::unique_ptr<CameraStreamHandler> handler);
|
||||
~GstCamera();
|
||||
|
||||
static void GstLibraryLoad();
|
||||
static void GstLibraryUnload();
|
||||
|
||||
bool Play();
|
||||
bool Pause();
|
||||
bool Stop();
|
||||
|
||||
bool SetZoomLevel(float zoom);
|
||||
float GetMaxZoomLevel() const { return max_zoom_level_; };
|
||||
float GetMinZoomLevel() const { return min_zoom_level_; };
|
||||
|
||||
const uint8_t* GetPreviewFrameBuffer();
|
||||
int32_t GetPreviewWidth() const { return width_; };
|
||||
int32_t GetPreviewHeight() const { return height_; };
|
||||
|
||||
private:
|
||||
struct GstCameraElements {
|
||||
GstElement* pipeline;
|
||||
GstElement* camerabin;
|
||||
GstElement* video_convert;
|
||||
GstElement* video_sink;
|
||||
GstElement* output;
|
||||
GstBus* bus;
|
||||
GstBuffer* buffer;
|
||||
};
|
||||
|
||||
static void HandoffHandler(GstElement* fakesink, GstBuffer* buf,
|
||||
GstPad* new_pad, gpointer user_data);
|
||||
static gboolean HandleGstMessage(GstBus* bus, GstMessage* message,
|
||||
gpointer user_data);
|
||||
|
||||
bool CreatePipeline();
|
||||
void DestroyPipeline();
|
||||
void Preroll();
|
||||
void GetZoomMaxMinSize(float& max, float& min);
|
||||
|
||||
GstCameraElements gst_;
|
||||
std::unique_ptr<uint32_t> pixels_;
|
||||
int32_t width_ = -1;
|
||||
int32_t height_ = -1;
|
||||
std::shared_mutex mutex_buffer_;
|
||||
std::unique_ptr<CameraStreamHandler> stream_handler_;
|
||||
float max_zoom_level_;
|
||||
float min_zoom_level_;
|
||||
float zoom_level_ = 1.0f;
|
||||
};
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_GST_CAMERA_H_
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef FLUTTER_PLUGIN_CAMERA_CAMERA_ELINUX_PLUGIN_H_
|
||||
#define FLUTTER_PLUGIN_CAMERA_CAMERA_ELINUX_PLUGIN_H_
|
||||
|
||||
#include <flutter_plugin_registrar.h>
|
||||
|
||||
#ifdef FLUTTER_PLUGIN_IMPL
|
||||
#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define FLUTTER_PLUGIN_EXPORT
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void CameraElinuxPluginRegisterWithRegistrar(
|
||||
FlutterDesktopPluginRegistrarRef registrar);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // FLUTTER_PLUGIN_CAMERA_CAMERA_ELINUX_PLUGIN_H_
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_AVAILABLE_CAMERAS_MESSAGE_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_AVAILABLE_CAMERAS_MESSAGE_H_
|
||||
|
||||
#include <flutter/binary_messenger.h>
|
||||
#include <flutter/encodable_value.h>
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
class AvailableCamerasMessage {
|
||||
public:
|
||||
AvailableCamerasMessage() = default;
|
||||
~AvailableCamerasMessage() = default;
|
||||
|
||||
// Prevent copying.
|
||||
AvailableCamerasMessage(AvailableCamerasMessage const&) = default;
|
||||
AvailableCamerasMessage& operator=(AvailableCamerasMessage const&) = default;
|
||||
|
||||
void SetName(const std::string& name) { name_ = name; }
|
||||
std::string GetName() const { return name_; }
|
||||
|
||||
void SetSensorOrientation(const int& sensor_orientation) {
|
||||
sensor_orientation_ = sensor_orientation;
|
||||
}
|
||||
int GetSensorOrientation() const { return sensor_orientation_; }
|
||||
|
||||
void SetLensFacing(const std::string& lens_facing) {
|
||||
lens_facing_ = lens_facing;
|
||||
}
|
||||
std::string GetLensFacing() const { return lens_facing_; }
|
||||
|
||||
flutter::EncodableValue ToMap() {
|
||||
flutter::EncodableMap map = {
|
||||
{flutter::EncodableValue("name"), flutter::EncodableValue(name_)},
|
||||
{flutter::EncodableValue("sensorOrientation"),
|
||||
flutter::EncodableValue(sensor_orientation_)},
|
||||
{flutter::EncodableValue("lensFacing"),
|
||||
flutter::EncodableValue(lens_facing_)}};
|
||||
return flutter::EncodableValue(map);
|
||||
}
|
||||
|
||||
static AvailableCamerasMessage FromMap(const flutter::EncodableValue& value) {
|
||||
AvailableCamerasMessage message;
|
||||
if (std::holds_alternative<flutter::EncodableMap>(value)) {
|
||||
auto map = std::get<flutter::EncodableMap>(value);
|
||||
|
||||
flutter::EncodableValue& name = map[flutter::EncodableValue("name")];
|
||||
if (std::holds_alternative<std::string>(name)) {
|
||||
message.SetName(std::get<std::string>(name));
|
||||
}
|
||||
|
||||
flutter::EncodableValue& sensor_orientation =
|
||||
map[flutter::EncodableValue("sensorOrientation")];
|
||||
if (std::holds_alternative<int>(sensor_orientation)) {
|
||||
message.SetSensorOrientation(std::get<int>(sensor_orientation));
|
||||
}
|
||||
|
||||
flutter::EncodableValue& lens_facing =
|
||||
map[flutter::EncodableValue("lensFacing")];
|
||||
if (std::holds_alternative<std::string>(lens_facing)) {
|
||||
message.SetLensFacing(std::get<std::string>(lens_facing));
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
int sensor_orientation_;
|
||||
std::string lens_facing_;
|
||||
};
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_AVAILABLE_CAMERAS_MESSAGE_H_
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_MESSAGES_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_MESSAGES_H_
|
||||
|
||||
#include "available_cameras_message.h"
|
||||
#include "orientation_message.h"
|
||||
#include "texture_message.h"
|
||||
#include "zoom_level_message.h"
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_MESSAGES_H_
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_ORIENTATION_MESSAGE_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_ORIENTATION_MESSAGE_H_
|
||||
|
||||
#include <flutter/binary_messenger.h>
|
||||
#include <flutter/encodable_value.h>
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include "types/orientation.h"
|
||||
|
||||
class OrientationMessage {
|
||||
public:
|
||||
OrientationMessage() = default;
|
||||
~OrientationMessage() = default;
|
||||
|
||||
// Prevent copying.
|
||||
OrientationMessage(OrientationMessage const&) = default;
|
||||
OrientationMessage& operator=(OrientationMessage const&) = default;
|
||||
|
||||
void SetOrientation(DeviceOrientation orientation) {
|
||||
orientation_ = orientation;
|
||||
}
|
||||
DeviceOrientation GetOrientation() const { return orientation_; }
|
||||
|
||||
flutter::EncodableValue ToMap() {
|
||||
flutter::EncodableMap map = {
|
||||
{flutter::EncodableValue("orientation"),
|
||||
flutter::EncodableValue(SerializeDeviceOrientation(orientation_))}};
|
||||
return flutter::EncodableValue(map);
|
||||
}
|
||||
|
||||
static OrientationMessage FromMap(const flutter::EncodableValue& value) {
|
||||
OrientationMessage message;
|
||||
if (std::holds_alternative<flutter::EncodableMap>(value)) {
|
||||
auto map = std::get<flutter::EncodableMap>(value);
|
||||
|
||||
flutter::EncodableValue& orientation =
|
||||
map[flutter::EncodableValue("orientation")];
|
||||
if (std::holds_alternative<std::string>(orientation)) {
|
||||
message.SetOrientation(
|
||||
DeserializeDeviceOrientation(std::get<std::string>(orientation)));
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
private:
|
||||
DeviceOrientation orientation_;
|
||||
};
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_ORIENTATION_MESSAGE_H_
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_TEXTURE_MESSAGE_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_TEXTURE_MESSAGE_H_
|
||||
|
||||
#include <flutter/binary_messenger.h>
|
||||
#include <flutter/encodable_value.h>
|
||||
|
||||
class TextureMessage {
|
||||
public:
|
||||
TextureMessage() = default;
|
||||
~TextureMessage() = default;
|
||||
|
||||
// Prevent copying.
|
||||
TextureMessage(TextureMessage const&) = default;
|
||||
TextureMessage& operator=(TextureMessage const&) = default;
|
||||
|
||||
void SetTextureId(int64_t texture_id) { texture_id_ = texture_id; }
|
||||
|
||||
int64_t GetTextureId() const { return texture_id_; }
|
||||
|
||||
flutter::EncodableValue ToMap() {
|
||||
flutter::EncodableMap map = {{flutter::EncodableValue("textureId"),
|
||||
flutter::EncodableValue(texture_id_)}};
|
||||
return flutter::EncodableValue(map);
|
||||
}
|
||||
|
||||
static TextureMessage FromMap(const flutter::EncodableValue& value) {
|
||||
TextureMessage message;
|
||||
if (std::holds_alternative<flutter::EncodableMap>(value)) {
|
||||
auto map = std::get<flutter::EncodableMap>(value);
|
||||
|
||||
flutter::EncodableValue& texture_id =
|
||||
map[flutter::EncodableValue("textureId")];
|
||||
if (std::holds_alternative<int32_t>(texture_id) ||
|
||||
std::holds_alternative<int64_t>(texture_id)) {
|
||||
message.SetTextureId(texture_id.LongValue());
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
private:
|
||||
int64_t texture_id_ = 0;
|
||||
};
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_TEXTURE_MESSAGE_H_
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_ZOOM_LEVEL_MESSAGE_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_ZOOM_LEVEL_MESSAGE_H_
|
||||
|
||||
#include <flutter/binary_messenger.h>
|
||||
#include <flutter/encodable_value.h>
|
||||
|
||||
#include <variant>
|
||||
|
||||
class ZoomLevelMessage {
|
||||
public:
|
||||
ZoomLevelMessage() = default;
|
||||
~ZoomLevelMessage() = default;
|
||||
|
||||
// Prevent copying.
|
||||
ZoomLevelMessage(ZoomLevelMessage const&) = default;
|
||||
ZoomLevelMessage& operator=(ZoomLevelMessage const&) = default;
|
||||
|
||||
void SetZoom(double zoom) { zoom_ = zoom; }
|
||||
double GetZoom() const { return zoom_; }
|
||||
|
||||
flutter::EncodableValue ToMap() {
|
||||
flutter::EncodableMap map = {
|
||||
{flutter::EncodableValue("zoom"), flutter::EncodableValue(zoom_)}};
|
||||
return flutter::EncodableValue(map);
|
||||
}
|
||||
|
||||
static ZoomLevelMessage FromMap(const flutter::EncodableValue& value) {
|
||||
ZoomLevelMessage message;
|
||||
if (std::holds_alternative<flutter::EncodableMap>(value)) {
|
||||
auto map = std::get<flutter::EncodableMap>(value);
|
||||
|
||||
flutter::EncodableValue& zoom = map[flutter::EncodableValue("zoom")];
|
||||
if (std::holds_alternative<double>(zoom)) {
|
||||
message.SetZoom(std::get<double>(zoom));
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
private:
|
||||
double zoom_;
|
||||
};
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_MESSAGES_ZOOM_LEVEL_MESSAGE_H_
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "method_channel/method_channel_camera.h"
|
||||
|
||||
#include <flutter/standard_method_codec.h>
|
||||
|
||||
namespace {
|
||||
constexpr char kChannelName[] = "flutter.io/cameraPlugin/camera";
|
||||
constexpr char kChannelMethodInitialized[] = "initialized";
|
||||
}; // namespace
|
||||
|
||||
MethodChannelCamera::MethodChannelCamera(flutter::PluginRegistrar* registrar,
|
||||
int64_t camera_id) {
|
||||
std::string channel_name = kChannelName + std::to_string(camera_id);
|
||||
channel_ = std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
|
||||
registrar->messenger(), channel_name.c_str(),
|
||||
&flutter::StandardMethodCodec::GetInstance());
|
||||
}
|
||||
|
||||
void MethodChannelCamera::SendInitializedEvent(
|
||||
CameraInitializedEvent& message) {
|
||||
auto value = std::make_unique<flutter::EncodableValue>(message.ToMap());
|
||||
Send(kChannelMethodInitialized, std::move(value));
|
||||
}
|
||||
|
||||
void MethodChannelCamera::Send(
|
||||
const std::string& method,
|
||||
std::unique_ptr<flutter::EncodableValue>&& arguments) {
|
||||
channel_->InvokeMethod(method, std::move(arguments));
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_METHOD_CHANNEL_METHOD_CHANNEL_CAMERA_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_METHOD_CHANNEL_METHOD_CHANNEL_CAMERA_H_
|
||||
|
||||
#include <flutter/encodable_value.h>
|
||||
#include <flutter/method_channel.h>
|
||||
#include <flutter/plugin_registrar.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "events/camera_initialized_event.h"
|
||||
|
||||
enum class CameraEventType {
|
||||
kError,
|
||||
kCameraClosing,
|
||||
kInitialized,
|
||||
};
|
||||
|
||||
class MethodChannelCamera {
|
||||
public:
|
||||
MethodChannelCamera(flutter::PluginRegistrar* registrar, int64_t camera_id);
|
||||
~MethodChannelCamera() = default;
|
||||
|
||||
void SendInitializedEvent(CameraInitializedEvent& message);
|
||||
|
||||
private:
|
||||
void Send(const std::string& method,
|
||||
std::unique_ptr<flutter::EncodableValue>&& arguments);
|
||||
|
||||
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> channel_;
|
||||
};
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_METHOD_CHANNEL_METHOD_CHANNEL_CAMERA_H_
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "method_channel/method_channel_device.h"
|
||||
|
||||
#include <flutter/standard_method_codec.h>
|
||||
|
||||
namespace {
|
||||
constexpr char kChannelName[] = "flutter.io/cameraPlugin/device";
|
||||
constexpr char kChannelMethodInitialized[] = "initialized";
|
||||
|
||||
constexpr char kOrientation[] = "orientation";
|
||||
}; // namespace
|
||||
|
||||
MethodChannelDevice::MethodChannelDevice(flutter::PluginRegistrar* registrar) {
|
||||
channel_ = std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
|
||||
registrar->messenger(), kChannelName,
|
||||
&flutter::StandardMethodCodec::GetInstance());
|
||||
}
|
||||
|
||||
void MethodChannelDevice::SendDeviceOrientationChangeEvent(
|
||||
const DeviceOrientation& orientation) {
|
||||
flutter::EncodableMap mp;
|
||||
mp[flutter::EncodableValue(kOrientation)] =
|
||||
flutter::EncodableValue(SerializeDeviceOrientation(orientation));
|
||||
auto value = std::make_unique<flutter::EncodableValue>(mp);
|
||||
|
||||
Send(kChannelMethodInitialized, std::move(value));
|
||||
}
|
||||
|
||||
void MethodChannelDevice::Send(
|
||||
const std::string& method,
|
||||
std::unique_ptr<flutter::EncodableValue>&& arguments) {
|
||||
channel_->InvokeMethod(method, std::move(arguments));
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_METHOD_CHANNEL_METHOD_CHANNEL_DEVICE_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_METHOD_CHANNEL_METHOD_CHANNEL_DEVICE_H_
|
||||
|
||||
#include <flutter/encodable_value.h>
|
||||
#include <flutter/method_channel.h>
|
||||
#include <flutter/plugin_registrar.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "types/orientation.h"
|
||||
|
||||
class MethodChannelDevice {
|
||||
public:
|
||||
MethodChannelDevice(flutter::PluginRegistrar* registrar);
|
||||
~MethodChannelDevice() = default;
|
||||
|
||||
void SendDeviceOrientationChangeEvent(const DeviceOrientation& orientation);
|
||||
|
||||
private:
|
||||
void Send(const std::string& method,
|
||||
std::unique_ptr<flutter::EncodableValue>&& arguments);
|
||||
|
||||
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> channel_;
|
||||
};
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_METHOD_CHANNEL_METHOD_CHANNEL_DEVICE_H_
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "types/exposure_mode.h"
|
||||
|
||||
std::string SerializeExposureMode(ExposureMode exposure_mode) {
|
||||
switch (exposure_mode) {
|
||||
case ExposureMode::kLocked:
|
||||
return "locked";
|
||||
case ExposureMode::kAuto:
|
||||
return "auto";
|
||||
default:
|
||||
return "auto";
|
||||
std::cerr << "Unknown ExposureMode value" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
ExposureMode DeserializeExposureMode(std::string str) {
|
||||
if (!str.compare("locked")) {
|
||||
return ExposureMode::kLocked;
|
||||
}
|
||||
if (!str.compare("auto")) {
|
||||
return ExposureMode::kAuto;
|
||||
}
|
||||
std::cerr << str.c_str() << " is not a valid ExposureMode value" << std::endl;
|
||||
return ExposureMode::kAuto;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_TYPES_EXPOSURE_MODE_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_TYPES_EXPOSURE_MODE_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// See:
|
||||
// flutter/plugins/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart
|
||||
enum class ExposureMode {
|
||||
kAuto,
|
||||
kLocked,
|
||||
};
|
||||
|
||||
std::string SerializeExposureMode(ExposureMode exposure_mode);
|
||||
ExposureMode DeserializeExposureMode(std::string str);
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_TYPES_EXPOSURE_MODE_H_
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "types/focus_mode.h"
|
||||
|
||||
std::string SerializeFocusMode(FocusMode focus_mode) {
|
||||
switch (focus_mode) {
|
||||
case FocusMode::kLocked:
|
||||
return "locked";
|
||||
case FocusMode::kAuto:
|
||||
return "auto";
|
||||
default:
|
||||
std::cerr << "Unknown FocusMode value" << std::endl;
|
||||
return "auto";
|
||||
}
|
||||
}
|
||||
|
||||
FocusMode DeserializeFocusMode(std::string str) {
|
||||
if (!str.compare("locked")) {
|
||||
return FocusMode::kLocked;
|
||||
}
|
||||
if (!str.compare("auto")) {
|
||||
return FocusMode::kAuto;
|
||||
}
|
||||
std::cerr << str.c_str() << " is not a valid FocusMode value" << std::endl;
|
||||
return FocusMode::kAuto;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_TYPES_FOCUS_MODE_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_TYPES_FOCUS_MODE_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// See:
|
||||
// flutter/plugins/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart
|
||||
enum class FocusMode {
|
||||
kAuto,
|
||||
kLocked,
|
||||
};
|
||||
|
||||
std::string SerializeFocusMode(FocusMode focus_mode);
|
||||
FocusMode DeserializeFocusMode(std::string str);
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_TYPES_FOCUS_MODE_H_
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "types/orientation.h"
|
||||
|
||||
std::string SerializeDeviceOrientation(DeviceOrientation orientation) {
|
||||
switch (orientation) {
|
||||
case DeviceOrientation::kPortraitUp:
|
||||
return "portraitUp";
|
||||
case DeviceOrientation::kLandscapeLeft:
|
||||
return "landscapeLeft";
|
||||
case DeviceOrientation::kPortraitDown:
|
||||
return "portraitDown";
|
||||
case DeviceOrientation::kLandscapeRight:
|
||||
return "landscapeRight";
|
||||
default:
|
||||
std::cerr << "Unknown DeviceOrientation value" << std::endl;
|
||||
return "landscapeLeft";
|
||||
}
|
||||
}
|
||||
|
||||
DeviceOrientation DeserializeDeviceOrientation(std::string str) {
|
||||
if (!str.compare("portraitUp")) {
|
||||
return DeviceOrientation::kPortraitUp;
|
||||
}
|
||||
if (!str.compare("landscapeLeft")) {
|
||||
return DeviceOrientation::kLandscapeLeft;
|
||||
}
|
||||
if (!str.compare("portraitDown")) {
|
||||
return DeviceOrientation::kPortraitDown;
|
||||
}
|
||||
if (!str.compare("landscapeRight")) {
|
||||
return DeviceOrientation::kLandscapeRight;
|
||||
}
|
||||
std::cerr << str.c_str() << " is not a valid DeviceOrientation value"
|
||||
<< std::endl;
|
||||
return DeviceOrientation::kLandscapeLeft;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2021 Sony Group Corporation. All rights reserved.
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_TYPES_ORIENTATION_H_
|
||||
#define PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_TYPES_ORIENTATION_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// See: [DeviceOrientation] in
|
||||
// flutter/packages/flutter/lib/src/services/system_chrome.dart
|
||||
enum class DeviceOrientation {
|
||||
kPortraitUp,
|
||||
kLandscapeLeft,
|
||||
kPortraitDown,
|
||||
kLandscapeRight,
|
||||
};
|
||||
|
||||
std::string SerializeDeviceOrientation(DeviceOrientation orientation);
|
||||
DeviceOrientation DeserializeDeviceOrientation(std::string str);
|
||||
|
||||
#endif // PACKAGES_CAMERA_CAMERA_ELINUX_CAMERA_TYPES_ORIENTATION_H_
|
||||
Reference in New Issue
Block a user