libcamera implements a pipeline handler locking mechanism based on advisory locks on media devices, to prevent concurrent access to cameras from the same pipeline handler from different processes (this only works between multiple libcamera instances, as other processes won't use advisory locks on media devices). A side effect of the implementation prevents multiple cameras created by the same pipeline handler from being used concurrently. Fix this by turning the PipelineHandler lock() and unlock() functions into acquire() and release(), with a use count to replace the boolean lock flag. The Camera class is updated accordingly. As a consequence of this change, the IPU3 pipeline handler will fail to operate properly when the cameras it exposes are operated concurrently. The android.hardware.camera2.cts.MultiViewTest#testDualCameraPreview test fails as a result. This should be fixed in the IPU3 pipeline handler to implement mutual exclusion between cameras. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Tested-by: David Plowman <david.plowman@raspberrypi.com>
76 lines
1.5 KiB
C++
76 lines
1.5 KiB
C++
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
/*
|
|
* Copyright (C) 2021, Google Inc.
|
|
*
|
|
* camera.h - Camera private data
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <list>
|
|
#include <memory>
|
|
#include <set>
|
|
#include <string>
|
|
|
|
#include <libcamera/base/class.h>
|
|
|
|
#include <libcamera/camera.h>
|
|
|
|
namespace libcamera {
|
|
|
|
class CameraControlValidator;
|
|
class PipelineHandler;
|
|
class Stream;
|
|
|
|
class Camera::Private : public Extensible::Private
|
|
{
|
|
LIBCAMERA_DECLARE_PUBLIC(Camera)
|
|
|
|
public:
|
|
Private(PipelineHandler *pipe);
|
|
~Private();
|
|
|
|
PipelineHandler *pipe() { return pipe_.get(); }
|
|
|
|
std::list<Request *> queuedRequests_;
|
|
ControlInfoMap controlInfo_;
|
|
ControlList properties_;
|
|
|
|
uint32_t requestSequence_;
|
|
|
|
const CameraControlValidator *validator() const { return validator_.get(); }
|
|
|
|
private:
|
|
enum State {
|
|
CameraAvailable,
|
|
CameraAcquired,
|
|
CameraConfigured,
|
|
CameraStopping,
|
|
CameraRunning,
|
|
};
|
|
|
|
bool isAcquired() const;
|
|
bool isRunning() const;
|
|
int isAccessAllowed(State state, bool allowDisconnected = false,
|
|
const char *from = __builtin_FUNCTION()) const;
|
|
int isAccessAllowed(State low, State high,
|
|
bool allowDisconnected = false,
|
|
const char *from = __builtin_FUNCTION()) const;
|
|
|
|
void disconnect();
|
|
void setState(State state);
|
|
|
|
std::shared_ptr<PipelineHandler> pipe_;
|
|
std::string id_;
|
|
std::set<Stream *> streams_;
|
|
std::set<const Stream *> activeStreams_;
|
|
|
|
bool disconnected_;
|
|
std::atomic<State> state_;
|
|
|
|
std::unique_ptr<CameraControlValidator> validator_;
|
|
};
|
|
|
|
} /* namespace libcamera */
|