# CameraAdaptor
CameraService functionality dealing with CameraHal 3.x reworked for Linux embedded.

#Client API Summary
 The device client and method definitions can be found within "qmmf_camera3_device_client.cc/h".
- Methods
	- __Camera3DeviceClient(CameraClientCallbacks clientCb)__
		- Description - Instantiates the device client object.
		- Arguments
			- clientCb - A set of user supplied callbacks that will get called in case of errors, notifications and results. For more information about this structure please check the "Commonly used structures and types" section.
		- Return values
			- None
    - __int32_t Initialize(const char \*pathToCameraModule, const char \*pathToGrallocModule)__
		- Description - Loads and initializes the user supplied CameraHal & Gralloc modules.
		- Arguments
			- pathToCameraModule - Path to the CameraHal module on the target filesystem.
			- pathToGrallocModule - Path to the Gralloc module on the target filesystem.
		- Return values
			- 0 - On success.
			- -EINVAL - In case of invalid paths.
			- -ENOSYS - In case this method called after a successful previous initialization.
    - __int32_t OpenCamera(uint32_t idx)__
		- Description - Opens a particular camera with given index. Please note that this method must be called after a succesfull initialization.
		- Arguments
			- idx - A valid camera index equal or less than getNumberOfCameras() - 1.
		- Return values
			- 0 - On success.
            - -EINVAL - In case of invalid index.
			- -ENOSYS - In case of failure or if this method is called twice and/or not after successfull initialization.
    - __int32_t BeginConfigure()__
		- Description - Currently this is a no-op. Implementation is pending. It should mark the start of a new stream configuration.
		- Arguments
			- None
		- Return values
			- 0 - On success.
    - __int32_t EndConfigure(bool isConstrainedHighSpeed = false)__
		- Description - Completes the stream configuration phase. It needs to get called after a camera is succesfully opened and at least one camera stream is created. This is a potentially expensive and slow operation so avoid calling it excessively.
		- Arguments
			- isConstrainedHighSpeed - Flags a stream configuration that will run in high speed constained mode. If not supplied by the user this flat is set to false by default.
		- Return values
			- 0 - On success.
			- -ENOSYS - In case this method called in a wrong state (check description).
			- -EINVAL - In case the created streams got rejects by CameraHal.
    - __int32_t DeleteStream(int streamId)__
		- Description - Removes a stream that was previously created by "createStream()". This method can be called during a "beginConfigure()"/"endConfigure()" block. A specifc stream can be deleted afterwards only if there are no pending or active requests for it and all buffers from the stream are returned by the user. Please note that all buffers allocated by this stream will also get released after the method completes.
		- Arguments
			- streamId - Stream Id of the stream that needs to be removed.
        - Return values
			- 0 - On success.
			- -EBUSY - In case the requirements for calling this method mentioned in the description are not met.
			- -EINVAL - In case the user given stream Id is incorrect (non-existing stream).
    - __int32_t CreateStream(const CameraStreamParameters &outputConfiguration)__
		- Description - Creates a new stream given the stream configuration parameters. This method can be called during a "beginConfigure()"/"endConfigure()" block or after a successful "endConfigure()" call. Please note that in the latter case the call can be expensive and/or slow as the streams will get re-configured.
		- Arguments
			- outputConfiguration - Steam parameters like size, format, usage etc. For more information about this structure please check the "Commonly used structures and types" section.
		- Return values
			- On success a stream Id which will be non-negative.
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
			- -EINVAL - In case the configuration parameters got rejected.
			- -ENOMEM - In case there are no resources for creating this new stream.
    - __int32_t CreateInputStream(const CameraInputStreamParameters &inputConfiguration)__
		- Description - Creates a new input stream given the stream configuration parameters. This method can be called during a "beginConfigure()"/"endConfigure()" block or after a successful "endConfigure()" call. Please note that in the latter case the call can be expensive and/or slow as the streams will get re-configured. Only one input stream can exist at any time in the camera. The user should submit input buffers along with their repspective metadata only when following conditions are met:
		- The input frame was generated by the same camera which will reprocess it.
		- The input frame was generated by the last valid and currently active stream configuration.
		- The reprocess request contains the metadata of the input buffer produced as result by the camera from the previous camera pass.
		- Arguments
			- inputConfiguration - Steam parameters like size, format, etc. For more information about this structure please check the "Commonly used structures and types" section.
		- Return values
			- On success a stream Id which will be non-negative.
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
			- -EINVAL - In case the configuration parameters got rejected.
			- -ENOMEM - In case there are no resources for creating this new stream.
    - __int32_t CreateDefaultRequest(int templateId, CameraMetadata* request)__
		- Description - Creates a default request given a specific template Id. This method can get called at any time after the camera is open.
		- Arguments
			- templateId - One of following values {CAMERA3_TEMPLATE_PREVIEW, CAMERA3_TEMPLATE_STILL_CAPTURE, CAMERA3_TEMPLATE_VIDEO_RECORD, CAMERA3_TEMPLATE_VIDEO_SNAPSHOT, CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG, CAMERA3_TEMPLATE_MANUAL}.
			- request - User supplied metadata which will store request in case of success.
		- Return values
			- 0 - On success
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
			- -EINVAL - In case the templated Id is invalid.
    - __int32_t SubmitRequest(Camera3Request request, bool streaming = false, int64_t* lastFrameNumber = NULL)__
		- Description - Submits a request to camera. This method can be called after a successful "endConfigure" call. The request should contain the stream Ids of streams that got successfully created. Please note that the user supplied settings will get copied.
		- Arguments
			- request - A single camera request that needs to be submitted. For more information about this structure please check the "Commonly used structures and types" section.
			- streaming - Indicates whether this is a repeating request.
			- lastFrameNumber - Returns the frame number of the last active request.
		- Return values
			- Non-negative request Id on success.
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
			- -EINVAL - In case the streams are not found, the settings are incorret or an error occurred when the request got queued.
    - __int32_t SubmitRequestList(List`<Camera3Request>` requests, bool streaming = false, int64_t* lastFrameNumber = NULL)__
		- Description - The same functionality and requirements as "submitRequest()" with the only notable difference that it accepts a list of requests instead of a single request.
		- Arguments
			- requests - A list of camera requests that need to be submitted. For more information about this structure please check the "Commonly used structures and types" section.
			- streaming - Indicates whether this is a repeating request.
			- lastFrameNumber - Returns the frame number of the last active request.
		- Return values
			- Non-negative request Id on success.
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
			- -EINVAL - In case the streams are not found, the settings are incorret or there was error when the request got queued.
    - __int32_t ReturnStreamBuffer(int32_t streamId, StreamBuffer buffer)__
		- Description - Returns a stream buffer to specific stream after the client has finished using it. This method can be called after successful stream configuration.
		- Arguments
			- streamId - The stream Id this buffer belongs to.
			- buffer - Stream buffer received as part of the stream callback registered during stream creation. For more information about this structure please check the "Commonly used structures and types" section.
		- Return values
			- 0 - On success
			- -ENOENT - In case the stream with given stream Id doesn't exist.
			- -EINVAL - In case the buffer doesn't belong to the stream.
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
    - __int32_t CancelRequest(int requestId, int64_t* lastFrameNumber = NULL)__
		- Description - Cancels all currently active streaming requests. This method can be called after successfull stream configuration.
		- Arguments
			- requestId - A valid request Id.
			- lastFrameNumber - Returns the frame number of the last active request.
		- Return values
			- 0 - On success
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
			- -EINVAL - In case no request with the user given Id is found.
    - __int32_t GetCameraInfo(uint32_t idx, CameraMetadata* info)__
		- Description - This will retrieve the static camera metadata/capabilities/characteristics of a given camera. The method can be called after a successful call to "initialize()".
		- Arguments
			- idx - Valid camera index.
			- info - Static camera metadata.
		- Return values
			- 0 - On success
			- -EINVAL - In case the user given metadata pointer is invalid or the camera index is incorrect.
			- -ENODEV - In case the CameraHal module is absent. This can happen if "initialize()" was not called previously or didn't complete successully.
    - __int32_t GetNumberOfCameras()__
		- Description - Returns the number of enumerated cameras on the system. The method can be called after a successful call to "initialize()".
		- Arguments
			- None
		- Return values
			- The number of detected cameras.
    - __int32_t WaitUntilIdle()__
		- Description - Blocks the caller until all pending requests complete or returns immediately if the camera is idle. The method can be called after a successful stream configuration.
		- Arguments
			- None
		- Return values
			- 0 - On success
			- -ETIMEDOUT - In case of a time out when waiting for all pending requests to complete.
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
    - __int32_t Flush(int64_t* lastFrameNumber = NULL)__
		- Description - Flushes all active and pending requests. The method can be called after a successful stream configuration.
		- Arguments
			- lastFrameNumber - Returns the frame number of the last active request.
		- Return values
			- 0 - On success
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
    - __int32_t Prepare(int streamId)__
		- Description - Prepares a stream by preallocating its buffers. The method can be called after a successful stream configuration. No requests should have been made involving this stream prior to this call. The user will get notified once prepare completes via the registered prepare callback.
		- Arguments
			- streamId - A valid stream Id.
		- Return values
			- 0 - On success
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
			- -EINVAL - In case the user given stream Id is invalid or an error ocurred during buffer allocation.
    - __int32_t TearDown(int streamId)__
		- Description - Tears down stream resources by freeing its buffers. The method can be called after a successful stream configuration and when the respective stream is idle without any pending requests.
		- Arguments
			- streamId - A valid stream Id.
		- Return values
			- 0 - On success
			- -ENOSYS - In case the requirements for calling this method mentioned in the description are not met.
			- -EINVAL - In case the user given stream Id is invalid or an error ocurred during buffer allocation.

#Commonly used structures and types
 These structures and types can be found within "qmmf_camera3_types.h"
 ```c++

typedef struct {
  CameraBufferMetaData info;
  int64_t timestamp;
  int64_t frame_number;
  android_dataspace data_space;
  buffer_handle_t handle;
} StreamBuffer;

// Please note that you can call all "Camera3DeviceClient" API methods
// from the same context of this callback.
typedef std::function<void(int32_t streamId, StreamBuffer buffer)>
    StreamCallback;

typedef struct {
  uint32_t width;
  uint32_t height;
  int32_t format;
  android_dataspace data_space;
  camera3_stream_rotation_t rotation;
  int32_t grallocFlags;
  uint32_t bufferCount;
  StreamCallback cb;
} CameraStreamParameters;

typedef struct Camera3Request_t {
  CameraMetadata metadata;
  Vector<int32_t> streamIds;
} Camera3Request;

typedef struct {
  int32_t requestId;
  int32_t burstId;
  int64_t frameNumber;
  int32_t partialResultCount;
  bool input;
} CaptureResultExtras;

typedef struct {
  CameraMetadata metadata;
  CaptureResultExtras resultExtras;
} CaptureResult;

enum CameraErrorCode {
  ERROR_CAMERA_INVALID_ERROR = -1,  // To indicate all invalid error codes
  ERROR_CAMERA_DISCONNECTED = 0,    // Indicates that the camera disconnected
  ERROR_CAMERA_DEVICE = 1,          // Indicates un-recoverable camera error
  ERROR_CAMERA_SERVICE = 2,         // Indicates issue with device client
  ERROR_CAMERA_REQUEST = 3,         // Indicates error during request processing
  ERROR_CAMERA_RESULT = 4,  // Indicates an error when generating request result
  ERROR_CAMERA_BUFFER = 5,  // Indicates an error during buffer processing
};

// Notifies about all sorts of errors that can happen during camera operation
typedef std::function<
    void(CameraErrorCode errorCode, const CaptureResultExtras &resultExtras)>
    ErrorCallback;
// Notifies the client that camera is idle with no pending requests
typedef std::function<void()> IdleCallback;
// Notifies about a shutter event
typedef std::function<void(const CaptureResultExtras &resultExtras,
                           int64_t timestamp)> ShutterCallback;
// Notifies when stream buffers got allocated
typedef std::function<void(int streamId)> PreparedCallback;
// Notifies about a new capture result
typedef std::function<void(const CaptureResult &result)> ResultCallback;

// Please note that these callbacks shouldn't get blocked for long durations.
// Also very important is to not to try and call "Camera3DeviceClient" API
// methods
// from the same context of these callbacks. This can lead to deadlocks!
typedef struct {
  ErrorCallback errorCb;
  IdleCallback idleCb;
  ShutterCallback shutterCb;
  PreparedCallback peparedCb;
  ResultCallback resultCb;
} CameraClientCallbacks;

//Please note that this callbacks need to return as fast as possible
//otherwise the camera framerate can be affected.
typedef std::function<void(StreamBuffer &buffer)> GetInputBuffer;
typedef std::function<void(StreamBuffer &buffer)> ReturnInputBuffer;

typedef struct {
  uint32_t width;
  uint32_t height;
  int32_t format;
  GetInputBuffer get_input_buffer;
  ReturnInputBuffer return_input_buffer;
} CameraInputStreamParameters;
 ```
