[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:
Hidenori Matsubayashi
2021-08-16 16:43:28 +09:00
committed by GitHub
parent 4c37b98e79
commit 999fdad59c
45 changed files with 3874 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
flutter/
+47
View File
@@ -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_
+309
View File
@@ -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;
}
+68
View File
@@ -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;
}
+22
View File
@@ -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_