mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
External: Switch to legacy V4L2 buffer mapping
Required for older kernels like 3.x Change-Id: I0680320b606727bdb0b22dab1df8c5954d623f10
This commit is contained in:
committed by
Yin-Chia Yeh
parent
fe1192ecfc
commit
9cdd6f9516
@@ -611,7 +611,12 @@ void ExternalCameraDeviceSession::invokeProcessCaptureResultCallback(
|
||||
}
|
||||
}
|
||||
}
|
||||
mCallback->processCaptureResult(results);
|
||||
auto status = mCallback->processCaptureResult(results);
|
||||
if (!status.isOk()) {
|
||||
ALOGE("%s: processCaptureResult ERROR : %s", __FUNCTION__,
|
||||
status.description().c_str());
|
||||
}
|
||||
|
||||
mProcessCaptureResultLock.unlock();
|
||||
}
|
||||
|
||||
@@ -1835,7 +1840,7 @@ int ExternalCameraDeviceSession::v4l2StreamOffLocked() {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
mV4l2Buffers.clear(); // VIDIOC_REQBUFS will fail if FDs are not clear first
|
||||
mV4L2BufferCount = 0;
|
||||
|
||||
// VIDIOC_STREAMOFF
|
||||
v4l2_buf_type capture_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
@@ -1955,24 +1960,20 @@ int ExternalCameraDeviceSession::configureV4l2StreamLocked(const SupportedV4L2Fo
|
||||
return NO_MEMORY;
|
||||
}
|
||||
|
||||
// VIDIOC_EXPBUF: export buffers as FD
|
||||
// VIDIOC_QUERYBUF: get buffer offset in the V4L2 fd
|
||||
// VIDIOC_QBUF: send buffer to driver
|
||||
mV4l2Buffers.resize(req_buffers.count);
|
||||
mV4L2BufferCount = req_buffers.count;
|
||||
for (uint32_t i = 0; i < req_buffers.count; i++) {
|
||||
v4l2_exportbuffer expbuf {};
|
||||
expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
expbuf.index = i;
|
||||
if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_EXPBUF, &expbuf)) < 0) {
|
||||
ALOGE("%s: EXPBUF %d failed: %s", __FUNCTION__, i, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
mV4l2Buffers[i].reset(expbuf.fd);
|
||||
|
||||
v4l2_buffer buffer = {
|
||||
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||
.index = i,
|
||||
.memory = V4L2_MEMORY_MMAP};
|
||||
|
||||
if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QUERYBUF, &buffer)) < 0) {
|
||||
ALOGE("%s: QUERYBUF %d failed: %s", __FUNCTION__, i, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) {
|
||||
ALOGE("%s: QBUF %d failed: %s", __FUNCTION__, i, strerror(errno));
|
||||
return -errno;
|
||||
@@ -2012,7 +2013,7 @@ sp<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked() {
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(mV4l2BufferLock);
|
||||
if (mNumDequeuedV4l2Buffers == mV4l2Buffers.size()) {
|
||||
if (mNumDequeuedV4l2Buffers == mV4L2BufferCount) {
|
||||
std::chrono::seconds timeout = std::chrono::seconds(kBufferWaitTimeoutSec);
|
||||
mLock.unlock();
|
||||
auto st = mV4L2BufferReturned.wait_for(lk, timeout);
|
||||
@@ -2032,7 +2033,7 @@ sp<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (buffer.index >= mV4l2Buffers.size()) {
|
||||
if (buffer.index >= mV4L2BufferCount) {
|
||||
ALOGE("%s: Invalid buffer id: %d", __FUNCTION__, buffer.index);
|
||||
return ret;
|
||||
}
|
||||
@@ -2048,7 +2049,7 @@ sp<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked() {
|
||||
}
|
||||
return new V4L2Frame(
|
||||
mV4l2StreamingFmt.width, mV4l2StreamingFmt.height, mV4l2StreamingFmt.fourcc,
|
||||
buffer.index, mV4l2Buffers[buffer.index].get(), buffer.bytesused);
|
||||
buffer.index, mV4l2Fd.get(), buffer.bytesused, buffer.m.offset);
|
||||
}
|
||||
|
||||
void ExternalCameraDeviceSession::enqueueV4l2Frame(const sp<V4L2Frame>& frame) {
|
||||
@@ -2243,7 +2244,7 @@ Status ExternalCameraDeviceSession::configureStreams(
|
||||
BufferUsage::CPU_WRITE_OFTEN |
|
||||
BufferUsage::CAMERA_OUTPUT;
|
||||
out->streams[i].v3_2.consumerUsage = 0;
|
||||
out->streams[i].v3_2.maxBuffers = mV4l2Buffers.size();
|
||||
out->streams[i].v3_2.maxBuffers = mV4L2BufferCount;
|
||||
|
||||
switch (config.streams[i].format) {
|
||||
case PixelFormat::BLOB:
|
||||
|
||||
@@ -40,9 +40,9 @@ const char* ExternalCameraDeviceConfig::kDefaultCfgPath = "/vendor/etc/external_
|
||||
|
||||
V4L2Frame::V4L2Frame(
|
||||
uint32_t w, uint32_t h, uint32_t fourcc,
|
||||
int bufIdx, int fd, uint32_t dataSize) :
|
||||
int bufIdx, int fd, uint32_t dataSize, uint64_t offset) :
|
||||
mWidth(w), mHeight(h), mFourcc(fourcc),
|
||||
mBufferIndex(bufIdx), mFd(fd), mDataSize(dataSize) {}
|
||||
mBufferIndex(bufIdx), mFd(fd), mDataSize(dataSize), mOffset(offset) {}
|
||||
|
||||
int V4L2Frame::map(uint8_t** data, size_t* dataSize) {
|
||||
if (data == nullptr || dataSize == nullptr) {
|
||||
@@ -53,7 +53,7 @@ int V4L2Frame::map(uint8_t** data, size_t* dataSize) {
|
||||
|
||||
std::lock_guard<std::mutex> lk(mLock);
|
||||
if (!mMapped) {
|
||||
void* addr = mmap(NULL, mDataSize, PROT_READ, MAP_SHARED, mFd, 0);
|
||||
void* addr = mmap(NULL, mDataSize, PROT_READ, MAP_SHARED, mFd, mOffset);
|
||||
if (addr == MAP_FAILED) {
|
||||
ALOGE("%s: V4L2 buffer map failed: %s", __FUNCTION__, strerror(errno));
|
||||
return -EINVAL;
|
||||
|
||||
@@ -293,7 +293,7 @@ protected:
|
||||
|
||||
bool mV4l2Streaming = false;
|
||||
SupportedV4L2Format mV4l2StreamingFmt;
|
||||
std::vector<unique_fd> mV4l2Buffers;
|
||||
size_t mV4L2BufferCount;
|
||||
|
||||
static const int kBufferWaitTimeoutSec = 3; // TODO: handle long exposure (or not allowing)
|
||||
std::mutex mV4l2BufferLock; // protect the buffer count and condition below
|
||||
|
||||
@@ -45,7 +45,8 @@ struct SupportedV4L2Format {
|
||||
// Also contains necessary information to enqueue the buffer back to V4L2 buffer queue
|
||||
class V4L2Frame : public virtual VirtualLightRefBase {
|
||||
public:
|
||||
V4L2Frame(uint32_t w, uint32_t h, uint32_t fourcc, int bufIdx, int fd, uint32_t dataSize);
|
||||
V4L2Frame(uint32_t w, uint32_t h, uint32_t fourcc, int bufIdx, int fd,
|
||||
uint32_t dataSize, uint64_t offset);
|
||||
~V4L2Frame() override;
|
||||
const uint32_t mWidth;
|
||||
const uint32_t mHeight;
|
||||
@@ -57,6 +58,7 @@ private:
|
||||
std::mutex mLock;
|
||||
const int mFd; // used for mmap but doesn't claim ownership
|
||||
const size_t mDataSize;
|
||||
const uint64_t mOffset; // used for mmap
|
||||
uint8_t* mData = nullptr;
|
||||
bool mMapped = false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user