diff --git a/packages/camera/elinux/camera_elinux_plugin.cc b/packages/camera/elinux/camera_elinux_plugin.cc index 2f279c2..4f841e0 100644 --- a/packages/camera/elinux/camera_elinux_plugin.cc +++ b/packages/camera/elinux/camera_elinux_plugin.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Group Corporation. All rights reserved. +// Copyright 2022 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. @@ -83,6 +83,9 @@ class CameraPlugin : public flutter::Plugin { void HandleInitializeCall( const flutter::EncodableValue* message, std::unique_ptr> result); + void HandleTakePictureCall( + const flutter::EncodableValue* message, + std::unique_ptr> result); void HandleStartImageStreamCall( const flutter::EncodableValue* message, std::unique_ptr> result); @@ -148,7 +151,7 @@ void CameraPlugin::HandleMethodCall( } else if (!method_name.compare(kCameraChannelApiInitialize)) { HandleInitializeCall(method_call.arguments(), std::move(result)); } else if (!method_name.compare(kCameraChannelApiTakePicture)) { - result->NotImplemented(); + HandleTakePictureCall(method_call.arguments(), std::move(result)); } else if (!method_name.compare(kCameraChannelApiPrepareForVideoRecording)) { result->NotImplemented(); } else if (!method_name.compare(kCameraChannelApiStartVideoRecording)) { @@ -285,6 +288,26 @@ void CameraPlugin::HandleInitializeCall( result->Success(); } +void CameraPlugin::HandleTakePictureCall( + const flutter::EncodableValue* message, + std::unique_ptr> result) { + if (!camera_) { + result->Error("Not found an active camera", + "Check for creating a camera device"); + return; + } + camera_->TakePicture([p_result = result.release()]( + const std::string& captured_file_path) { + if (!captured_file_path.empty()) { + flutter::EncodableValue value(captured_file_path); + p_result->Success(value); + } else { + p_result->Error("Failed to capture", "Failed to capture a camera image"); + } + delete p_result; + }); +} + void CameraPlugin::HandleStartImageStreamCall( const flutter::EncodableValue* message, std::unique_ptr> result) { diff --git a/packages/camera/elinux/gst_camera.cc b/packages/camera/elinux/gst_camera.cc index 8440c30..9bb0e47 100644 --- a/packages/camera/elinux/gst_camera.cc +++ b/packages/camera/elinux/gst_camera.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Group Corporation. All rights reserved. +// Copyright 2022 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. @@ -77,6 +77,19 @@ bool GstCamera::Stop() { return true; } +void GstCamera::TakePicture(OnNotifyCaptured on_notify_captured) { + if (!gst_.camerabin) { + std::cerr << "Failed to take a picture" << std::endl; + return; + } + + on_notify_captured_ = on_notify_captured; + std::string filename = + g_strdup_printf("captured_%04u.jpg", captured_count_++); + g_object_set(gst_.camerabin, "location", filename.c_str(), NULL); + g_signal_emit_by_name(gst_.camerabin, "start-capture", NULL); +} + bool GstCamera::SetZoomLevel(float zoom) { if (zoom_level_ == zoom) { return true; @@ -280,6 +293,18 @@ void GstCamera::HandoffHandler(GstElement* fakesink, GstBuffer* buf, gboolean GstCamera::HandleGstMessage(GstBus* bus, GstMessage* message, gpointer user_data) { switch (GST_MESSAGE_TYPE(message)) { + case GST_MESSAGE_ELEMENT: { + auto const* st = gst_message_get_structure(message); + if (st) { + auto* self = reinterpret_cast(user_data); + if (gst_structure_has_name(st, "image-done") && + self->on_notify_captured_) { + auto const* filename = gst_structure_get_string(st, "filename"); + self->on_notify_captured_(filename); + } + } + break; + } case GST_MESSAGE_WARNING: { gchar* debug; GError* error; diff --git a/packages/camera/elinux/gst_camera.h b/packages/camera/elinux/gst_camera.h index 5cf5048..0ef125d 100644 --- a/packages/camera/elinux/gst_camera.h +++ b/packages/camera/elinux/gst_camera.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Group Corporation. All rights reserved. +// Copyright 2022 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. @@ -7,6 +7,7 @@ #include +#include #include #include #include @@ -15,6 +16,9 @@ class GstCamera { public: + using OnNotifyCaptured = + std::function; + GstCamera(std::unique_ptr handler); ~GstCamera(); @@ -25,6 +29,8 @@ class GstCamera { bool Pause(); bool Stop(); + void TakePicture(OnNotifyCaptured on_notify_captured); + bool SetZoomLevel(float zoom); float GetMaxZoomLevel() const { return max_zoom_level_; }; float GetMinZoomLevel() const { return min_zoom_level_; }; @@ -59,10 +65,13 @@ class GstCamera { int32_t width_ = -1; int32_t height_ = -1; std::shared_mutex mutex_buffer_; - std::unique_ptr stream_handler_; + std::unique_ptr stream_handler_ = nullptr; float max_zoom_level_; float min_zoom_level_; float zoom_level_ = 1.0f; + int captured_count_ = 0; + + OnNotifyCaptured on_notify_captured_ = nullptr; }; #endif // PACKAGES_CAMERA_CAMERA_ELINUX_GST_CAMERA_H_