Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

camera: add TakePicture API implementation #60

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions packages/camera/elinux/camera_elinux_plugin.cc
Original file line number Diff line number Diff line change
@@ -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.

Expand Down Expand Up @@ -83,6 +83,9 @@ class CameraPlugin : public flutter::Plugin {
void HandleInitializeCall(
const flutter::EncodableValue* message,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void HandleTakePictureCall(
const flutter::EncodableValue* message,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void HandleStartImageStreamCall(
const flutter::EncodableValue* message,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -285,6 +288,26 @@ void CameraPlugin::HandleInitializeCall(
result->Success();
}

void CameraPlugin::HandleTakePictureCall(
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;
}
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<flutter::MethodResult<flutter::EncodableValue>> result) {
Expand Down
27 changes: 26 additions & 1 deletion packages/camera/elinux/gst_camera.cc
Original file line number Diff line number Diff line change
@@ -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.

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<GstCamera*>(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;
Expand Down
13 changes: 11 additions & 2 deletions packages/camera/elinux/gst_camera.h
Original file line number Diff line number Diff line change
@@ -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.

Expand All @@ -7,6 +7,7 @@

#include <gst/gst.h>

#include <functional>
#include <memory>
#include <shared_mutex>
#include <string>
Expand All @@ -15,6 +16,9 @@

class GstCamera {
public:
using OnNotifyCaptured =
std::function<void(const std::string& captured_file_path)>;

GstCamera(std::unique_ptr<CameraStreamHandler> handler);
~GstCamera();

Expand All @@ -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_; };
Expand Down Expand Up @@ -59,10 +65,13 @@ class GstCamera {
int32_t width_ = -1;
int32_t height_ = -1;
std::shared_mutex mutex_buffer_;
std::unique_ptr<CameraStreamHandler> stream_handler_;
std::unique_ptr<CameraStreamHandler> 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_