Skip to content

Commit

Permalink
camera: add TakePicture API implementation (#60)
Browse files Browse the repository at this point in the history
One of implementation in #6

Signed-off-by: Hidenori Matsubayashi <[email protected]>
  • Loading branch information
HidenoriMatsubayashi authored Oct 23, 2022
1 parent be5e050 commit ca81dbb
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 5 deletions.
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_

0 comments on commit ca81dbb

Please sign in to comment.