blob: f8187346d9e626fc5eb1e44e495e7a83b72cd178 [file] [log] [blame]
/*
* Copyright 2020 The Chromium OS 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 CAMERA_COMMON_LIBCAMERA_CONNECTOR_CAMERA_CLIENT_OPS_H_
#define CAMERA_COMMON_LIBCAMERA_CONNECTOR_CAMERA_CLIENT_OPS_H_
#include <vector>
#include <base/callback.h>
#include <base/containers/flat_map.h>
#include <base/synchronization/lock.h>
#include <base/threading/thread.h>
#include <mojo/public/cpp/bindings/binding.h>
#include "common/libcamera_connector/stream_buffer_manager.h"
#include "common/libcamera_connector/types.h"
#include "cros-camera/camera_service_connector.h"
#include "mojo/camera3.mojom.h"
namespace cros {
// CameraClientOps is an implementation of mojom::Camera3CallbackOps and
// manages mojom::Camera3DeviceOps as well. CameraClientOps is expected to be
// initialized every time before a capture session can be started.
//
// When starting a capture session,
// 1. Init() is called to initialize CameraClientOps and
// mojom::Camera3DeviceOpsRequest is returned. Subsequent calls to the
// member functions are expected to be run on the same sequence the
// Init() call ran on.
// 2. The user of this class should then bind mojom::Camera3DeviceOpsRequest
// before calling StartCapture()
// 3. When StartCapture() is called, it's expected that |device_ops_| is bound
// CameraClientOps would proceed to start the capture loop and send capture
// results via |result_callback_|.
// 4. When StopCapture() is called, the capture loop is stopped immediately.
// To reuse this class, Init() needs to be called to re-initialize the
// class.
//
// Error handling: When a serious error is encountered when configuring the
// capture session or the camera device reported a serious error,
// CameraClientOps notifies the error to the user of this class with by sending
// -ENODEV status in the result callback, and the user is expected to close the
// camera device immediately and stop using CameraClientOps.
class CameraClientOps : public mojom::Camera3CallbackOps {
public:
static const int kStreamId = 0;
using CaptureResultCallback =
base::Callback<void(const cros_cam_capture_result_t&)>;
CameraClientOps();
// Initializes the class and returns mojom::Camera3DeviceOpsRequest to be
// bound. Subsequent calls to other member functions are expected to be run on
// the same sequence the Init() call ran on.
mojom::Camera3DeviceOpsRequest Init(CaptureResultCallback result_callback);
// Starts the capture session. StartCapture() initializes the device,
// configures streams, and starts sending capture requests in a loop. Note
// that |device_ops_| should be bound before the user makes this call.
void StartCapture(int32_t camera_id,
const cros_cam_format_info_t* format,
int32_t jpeg_max_size);
// Stops the capture session and calls |close_callback| when the device is
// closed. The capture loop is immediately stopped, but capture results might
// still be sent after this call.
void StopCapture(IntOnceCallback close_callback);
// Resets CameraClientOps. This halts all ongoing CameraClientOps operations
// and resets the class to an uninitialized state (i.e., Init() can be called
// to reinitialize the class).
void Reset();
// ProcessCaptureResult is an implementation of ProcessCaptureResult in
// Camera3CallbackOps. It receives the result metadata and filled buffers from
// the camera service.
void ProcessCaptureResult(mojom::Camera3CaptureResultPtr result) override;
// Notify is an implementation of Notify in Camera3CallbackOps. It receives
// shutter messages and error notifications.
void Notify(mojom::Camera3NotifyMsgPtr msg) override;
private:
void InitializeDevice();
void OnInitializedDevice(int32_t result);
void ConfigureStreams();
void OnConfiguredStreams(
int32_t result,
mojom::Camera3StreamConfigurationPtr updated_config,
base::flat_map<uint64_t, std::vector<mojom::Camera3StreamBufferPtr>>
allocated_buffers);
void ConstructDefaultRequestSettings();
void OnConstructedDefaultRequestSettings(mojom::CameraMetadataPtr settings);
void ConstructCaptureRequest();
void ConstructCaptureRequestOnThread();
void ProcessCaptureRequest(mojom::Camera3CaptureRequestPtr request);
void OnProcessedCaptureRequest(int32_t result);
void SendCaptureResult(int status, cros_cam_frame_t* frame);
void OnClosedDevice(IntOnceCallback close_callback, int32_t result);
// All public functions and IPC calls through |device_ops_| are expected to be
// done on |ops_runner_|.
scoped_refptr<base::SequencedTaskRunner> ops_runner_;
// |capturing_| indicates whether device has been opened. We use |capturing_|
// to prevent us from sending additional mojo IPC calls after calling
// Camera3DeviceOps::Close(). See b/166725158 for context.
bool capturing_;
mojom::Camera3DeviceOpsPtr device_ops_;
mojo::Binding<mojom::Camera3CallbackOps> camera3_callback_ops_;
CaptureResultCallback result_callback_;
int32_t request_camera_id_;
cros_cam_format_info_t request_format_;
int32_t jpeg_max_size_;
StreamBufferManager buffer_manager_;
mojom::Camera3StreamConfigurationPtr stream_config_;
mojom::CameraMetadataPtr request_settings_;
uint32_t frame_number_;
};
} // namespace cros
#endif // CAMERA_COMMON_LIBCAMERA_CONNECTOR_CAMERA_CLIENT_OPS_H_