blob: 4694caa5ac160e181b3a8fdbc923e7d885ec3bfe [file] [log] [blame]
/*
* Copyright (C) 2014-2019 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _CAMERA3_HAL_CAMERA3REQUEST_H_
#define _CAMERA3_HAL_CAMERA3REQUEST_H_
#include <camera/camera_metadata.h>
#include <hardware/camera3.h>
#include <vector>
#include <memory>
#include <map>
#include <mutex>
#include "CameraStream.h"
#include "CameraBuffer.h"
namespace cros {
namespace intel {
/**
* This define is only used for the purpose of the allocation of output buffer
* pool
* The exact value for this should be coming from the static metadata tag
* maxNumOutputStreams. But at this stage we cannot query it because we do
* not know the camera id. This value should always be bigger than the static
* tag.
*/
#define MAX_NUMBER_OUTPUT_STREAMS 8
/**
* \enum
* This enum is used as index when acquiring the partial result metadata buffer
* In theory there should be one metadata partial result per thread context
* that writes result
* in IPU3 ControlUnit and Capture Unit update metadata result and return it
*/
enum PartialResultEnum {
CONTROL_UNIT_PARTIAL_RESULT = 0,
PARTIAL_RESULT_COUNT /* keep last to use as counter */
};
/**
* \class IRequestCallback
*
* This interface is implemented by the ResultProcessor
* It is used by CameraStreams to report that an output buffer that belongs to
* a particular request is done
* It is used by PSL entities to report that part of the result information is
* ready
*/
class IRequestCallback {
public:
virtual ~IRequestCallback() {}
virtual status_t shutterDone(Camera3Request* request,
int64_t timestamp) = 0;
virtual status_t metadataDone(Camera3Request* request,
int resultIndex = -1) = 0;
virtual status_t bufferDone(Camera3Request* request,
std::shared_ptr<CameraBuffer> buffer) = 0;
};
// generic template for objects that are shared among threads
// If you see deadlocks with SharedObject, you probably didn't let the previous
// incarnation around the same object to go out of scope (destructor releases).
template<typename TYPE, typename MEMBERTYPE>
class SharedObject {
public:
explicit SharedObject(TYPE &p) :
mMembers(p.mMembers), mSharedObject(nullptr), mRefSharedObject(p) {
mRefSharedObject.mLock.lock();
}
explicit SharedObject(TYPE* p) :
mMembers(p->mMembers), mSharedObject(p), mRefSharedObject(*p) {
mSharedObject->mLock.lock();
}
~SharedObject() {
mRefSharedObject.mLock.unlock();
}
MEMBERTYPE &mMembers;
private:
SharedObject();
SharedObject(const SharedObject &);
SharedObject &operator=(const SharedObject &);
TYPE* mSharedObject;
TYPE &mRefSharedObject;
};
/**
* \class Camera3Request
*
* Internal representation of a user request (capture or re-process)
* Objects of this class are initialized for each capture request received
* by the camera device. Once those objects are initialized the request is safe
* for processing by the Platform Specific Layer.
*
* Basic integrity checks are performed on initialization.
* The class also has other utility methods to ease the PSL implementations
*
*
*/
class Camera3Request {
public:
Camera3Request();
virtual ~Camera3Request();
status_t init(camera3_capture_request* req,
IRequestCallback* cb, android::CameraMetadata &settings, int cameraId);
void deInit();
/* access methods */
unsigned int getNumberOutputBufs();
bool hasInputBuf();
int getBufferCountOfFormat(int format) const;
int getId();
int getpartialResultCount() { return mPartialResultBuffers.size(); }
int getCameraId() {return mCameraId;}
android::CameraMetadata* getPartialResultBuffer(unsigned int index);
const android::CameraMetadata* getSettings() const;
const std::vector<camera3_stream_buffer>* getOutputBuffers();
const camera3_stream_buffer* getInputBuffer();
const std::vector<CameraStream*>* getOutputStreams();
const CameraStream* getInputStream();
std::shared_ptr<CameraBuffer> findBuffer(const CameraStream* stream, bool warn = true);
bool isInputBuffer(std::shared_ptr<CameraBuffer> buffer);
bool shouldSwapWidthHeight() const;
void setSeqenceId(int seqenceId) {mSeqenceId = seqenceId; }
int seqenceId() const {return mSeqenceId; }
class Members {
public:
android::CameraMetadata mSettings;
};
IRequestCallback * mCallback;
private: /* methods */
status_t checkInputStream(camera3_capture_request* request3);
status_t checkOutputStreams(camera3_capture_request* request3);
status_t initPartialResultBuffers(int cameraId);
status_t allocatePartialResultBuffers(int partialResultCount);
void freePartialResultBuffers(void);
void reAllocateResultBuffer(camera_metadata_t* m, int index);
private: /* types and members */
// following macro adds the parts that SharedObject template requires, in practice:
// mMembers, mLock and friendship with the SharedObject template
Members mMembers;
mutable std::mutex mLock; /* protects mMembers and SharedObjects */
friend class SharedObject<Camera3Request, Camera3Request::Members>;
friend class SharedObject<const Camera3Request, const Camera3Request::Members>;
bool mInitialized;
android::CameraMetadata mSettings; /* request settings metadata. Always contains a
valid metadata buffer even if the request
had nullptr */
std::mutex mAccessLock; /* protects mInBuffers, mOutBufs and mRequestId,
to ensure thread safe access to private
camera3_capture_request and camera3_stream_buffer
members*/
unsigned int mRequestId; /* the frame_count from the original request struct */
int mCameraId;
int mSeqenceId;
camera3_capture_request mRequest3;
std::vector<camera3_stream_buffer> mOutBufs;
bool mHasInBuf;
camera3_stream_buffer mInBuf;
std::vector<CameraStream*> mOutStreams;
CameraStream* mInStream;
std::shared_ptr<CameraBuffer> mOutCamBufPool[MAX_NUMBER_OUTPUT_STREAMS];
std::vector<std::shared_ptr<CameraBuffer> > mOutCamBufs;
std::shared_ptr<CameraBuffer> mInCamBuf;
std::map<int, int> mBuffersPerFormat;
/* Partial result support */
bool mResultBufferAllocated;
bool mShouldSwapWidthHeight;
/**
* \struct MemoryManagedMetadata
* This struct is used to store the metadata buffers that are created from
* memory managed by the HAL.
* This is needed to avoid continuous allocation/de-allocation of metadata
* buffers. The underlying memory for this metadata buffes is allocated
* once but the metadata object can be cleared many times.
* The need for this struct comes from the fact that there is no API to
* clear the contents of a metadata buffer completely.
*/
typedef struct {
android::CameraMetadata *metaBuf;
void *baseBuf; /* ownership mPartialResultBuffers */
size_t size;
int dataCap;
int entryCap;
} MemoryManagedMetadata;
std::vector<MemoryManagedMetadata> mPartialResultBuffers;
};
} /* namespace intel */
} /* namespace cros */
#endif /* _CAMERA3_HAL_CAMERA3REQUEST_H_ */