summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Söderlund <niklas.soderlund@ragnatech.se>2019-11-21 20:12:38 +0100
committerNiklas Söderlund <niklas.soderlund@ragnatech.se>2020-01-12 16:10:37 +0100
commit5967363c0b99a59f3526c51917572b807324e389 (patch)
tree134a8e070813bca1dfbf72e10d4443e951757e8d
parentdea689e1f260b904697a9c2f3d05b7b5068d85e1 (diff)
libcamera: buffer: Move captured metadata to FrameMetadata
Move the metadata retrieved when dequeuing a V4L2 buffer into a FrameMetadata object. This is done as a step to migrate to the FrameBuffer interface as the functions added to Buffer around FrameMetadata match the ones in FrameBuffer. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--include/libcamera/buffer.h16
-rw-r--r--src/android/camera_device.cpp4
-rw-r--r--src/cam/buffer_writer.cpp2
-rw-r--r--src/cam/capture.cpp13
-rw-r--r--src/libcamera/buffer.cpp76
-rw-r--r--src/libcamera/pipeline/ipu3/ipu3.cpp4
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1.cpp8
-rw-r--r--src/libcamera/request.cpp2
-rw-r--r--src/libcamera/v4l2_videodevice.cpp25
-rw-r--r--src/qcam/main_window.cpp13
-rw-r--r--src/v4l2/v4l2_camera.cpp8
-rw-r--r--src/v4l2/v4l2_camera.h4
-rw-r--r--src/v4l2/v4l2_camera_proxy.cpp4
-rw-r--r--test/camera/buffer_import.cpp2
-rw-r--r--test/camera/capture.cpp2
-rw-r--r--test/v4l2_videodevice/buffer_sharing.cpp8
16 files changed, 78 insertions, 113 deletions
diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h
index 55d08e27..0eb84c32 100644
--- a/include/libcamera/buffer.h
+++ b/include/libcamera/buffer.h
@@ -99,12 +99,6 @@ private:
class Buffer final
{
public:
- enum Status {
- BufferSuccess,
- BufferError,
- BufferCancelled,
- };
-
Buffer(unsigned int index = -1, const Buffer *metadata = nullptr);
Buffer(const Buffer &) = delete;
Buffer &operator=(const Buffer &) = delete;
@@ -113,11 +107,8 @@ public:
const std::array<int, 3> &dmabufs() const { return dmabuf_; }
BufferMemory *mem() { return mem_; }
- unsigned int bytesused() const { return bytesused_; }
- uint64_t timestamp() const { return timestamp_; }
- unsigned int sequence() const { return sequence_; }
+ const FrameMetadata &metadata() const { return metadata_; };
- Status status() const { return status_; }
Request *request() const { return request_; }
Stream *stream() const { return stream_; }
@@ -133,11 +124,8 @@ private:
std::array<int, 3> dmabuf_;
BufferMemory *mem_;
- unsigned int bytesused_;
- uint64_t timestamp_;
- unsigned int sequence_;
+ FrameMetadata metadata_;
- Status status_;
Request *request_;
Stream *stream_;
};
diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 09588c16..ebe91ea8 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -803,11 +803,11 @@ void CameraDevice::requestComplete(Request *request)
if (status == CAMERA3_BUFFER_STATUS_OK) {
notifyShutter(descriptor->frameNumber,
- libcameraBuffer->timestamp());
+ libcameraBuffer->metadata().timestamp);
captureResult.partial_result = 1;
resultMetadata = getResultMetadata(descriptor->frameNumber,
- libcameraBuffer->timestamp());
+ libcameraBuffer->metadata().timestamp);
captureResult.result = resultMetadata->get();
}
diff --git a/src/cam/buffer_writer.cpp b/src/cam/buffer_writer.cpp
index 765a1762..41ef4b0a 100644
--- a/src/cam/buffer_writer.cpp
+++ b/src/cam/buffer_writer.cpp
@@ -33,7 +33,7 @@ int BufferWriter::write(Buffer *buffer, const std::string &streamName)
if (pos != std::string::npos) {
std::stringstream ss;
ss << streamName << "-" << std::setw(6)
- << std::setfill('0') << buffer->sequence();
+ << std::setfill('0') << buffer->metadata().sequence;
filename.replace(pos, 1, ss.str());
}
diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp
index 1a4dbe7c..da942f56 100644
--- a/src/cam/capture.cpp
+++ b/src/cam/capture.cpp
@@ -154,9 +154,18 @@ void Capture::requestComplete(Request *request)
Buffer *buffer = it->second;
const std::string &name = streamName_[stream];
+ const FrameMetadata &metadata = buffer->metadata();
+
info << " " << name
- << " seq: " << std::setw(6) << std::setfill('0') << buffer->sequence()
- << " bytesused: " << buffer->bytesused();
+ << " seq: " << std::setw(6) << std::setfill('0') << metadata.sequence
+ << " bytesused: ";
+
+ unsigned int nplane = 0;
+ for (const FrameMetadata::Plane &plane : metadata.planes) {
+ info << plane.bytesused;
+ if (++nplane < metadata.planes.size())
+ info << "/";
+ }
if (writer_)
writer_->write(buffer, name);
diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp
index 8c8be4ac..92ac2838 100644
--- a/src/libcamera/buffer.cpp
+++ b/src/libcamera/buffer.cpp
@@ -178,20 +178,6 @@ void BufferPool::destroyBuffers()
*/
/**
- * \enum Buffer::Status
- * Buffer completion status
- * \var Buffer::BufferSuccess
- * The buffer has completed with success and contains valid data. All its other
- * metadata (such as bytesused(), timestamp() or sequence() number) are valid.
- * \var Buffer::BufferError
- * The buffer has completed with an error and doesn't contain valid data. Its
- * other metadata are valid.
- * \var Buffer::BufferCancelled
- * The buffer has been cancelled due to capture stop. Its other metadata are
- * invalid and shall not be used.
- */
-
-/**
* \brief Construct a buffer not associated with any stream
*
* This method constructs an orphaned buffer not associated with any stream. It
@@ -199,19 +185,15 @@ void BufferPool::destroyBuffers()
* for a stream with Stream::createBuffer().
*/
Buffer::Buffer(unsigned int index, const Buffer *metadata)
- : index_(index), dmabuf_({ -1, -1, -1 }),
- status_(Buffer::BufferSuccess), request_(nullptr),
+ : index_(index), dmabuf_({ -1, -1, -1 }), request_(nullptr),
stream_(nullptr)
{
- if (metadata) {
- bytesused_ = metadata->bytesused_;
- sequence_ = metadata->sequence_;
- timestamp_ = metadata->timestamp_;
- } else {
- bytesused_ = 0;
- sequence_ = 0;
- timestamp_ = 0;
- }
+ if (metadata)
+ metadata_ = metadata->metadata();
+ else
+ metadata_ = {};
+
+ metadata_.status = FrameMetadata::FrameSuccess;
}
/**
@@ -242,39 +224,13 @@ Buffer::Buffer(unsigned int index, const Buffer *metadata)
*/
/**
- * \fn Buffer::bytesused()
- * \brief Retrieve the number of bytes occupied by the data in the buffer
- * \return Number of bytes occupied in the buffer
- */
-
-/**
- * \fn Buffer::timestamp()
- * \brief Retrieve the time when the buffer was processed
- *
- * The timestamp is expressed as a number of nanoseconds since the epoch.
- *
- * \return Timestamp when the buffer was processed
- */
-
-/**
- * \fn Buffer::sequence()
- * \brief Retrieve the buffer sequence number
- *
- * The sequence number is a monotonically increasing number assigned to the
- * buffer processed by the stream. Gaps in the sequence numbers indicate
- * dropped frames.
- *
- * \return Sequence number of the buffer
- */
-
-/**
- * \fn Buffer::status()
- * \brief Retrieve the buffer status
+ * \fn Buffer::metadata()
+ * \brief Retrieve the buffer metadata
*
- * The buffer status reports whether the buffer has completed successfully
- * (BufferSuccess) or if an error occurred (BufferError).
+ * The buffer metadata is updated when the buffer contents are modified, for
+ * example when a frame has been captured to the buffer by the hardware.
*
- * \return The buffer status
+ * \return Metadata for the buffer
*/
/**
@@ -310,10 +266,10 @@ Buffer::Buffer(unsigned int index, const Buffer *metadata)
*/
void Buffer::cancel()
{
- bytesused_ = 0;
- timestamp_ = 0;
- sequence_ = 0;
- status_ = BufferCancelled;
+ metadata_.status = FrameMetadata::FrameCancelled;
+ metadata_.sequence = 0;
+ metadata_.timestamp = 0;
+ metadata_.planes = {};
}
/**
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 6d8c3fad..34fc7929 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -928,7 +928,7 @@ int PipelineHandlerIPU3::registerCameras()
void IPU3CameraData::imguInputBufferReady(Buffer *buffer)
{
/* \todo Handle buffer failures when state is set to BufferError. */
- if (buffer->status() == Buffer::BufferCancelled)
+ if (buffer->metadata().status == FrameMetadata::FrameCancelled)
return;
cio2_.output_->queueBuffer(buffer);
@@ -962,7 +962,7 @@ void IPU3CameraData::imguOutputBufferReady(Buffer *buffer)
void IPU3CameraData::cio2BufferReady(Buffer *buffer)
{
/* \todo Handle buffer failures when state is set to BufferError. */
- if (buffer->status() == Buffer::BufferCancelled)
+ if (buffer->metadata().status == FrameMetadata::FrameCancelled)
return;
imgu_->input_->queueBuffer(buffer);
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 1e445715..979b670e 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -100,10 +100,10 @@ public:
ASSERT(frameOffset(SOE) == 0);
utils::time_point soe = std::chrono::time_point<utils::clock>()
- + std::chrono::nanoseconds(buffer->timestamp())
+ + std::chrono::nanoseconds(buffer->metadata().timestamp)
+ timeOffset(SOE);
- notifyStartOfExposure(buffer->sequence(), soe);
+ notifyStartOfExposure(buffer->metadata().sequence, soe);
}
void setDelay(unsigned int type, int frame, int msdelay)
@@ -994,8 +994,8 @@ void PipelineHandlerRkISP1::bufferReady(Buffer *buffer)
data->timeline_.bufferReady(buffer);
- if (data->frame_ <= buffer->sequence())
- data->frame_ = buffer->sequence() + 1;
+ if (data->frame_ <= buffer->metadata().sequence)
+ data->frame_ = buffer->metadata().sequence + 1;
completeBuffer(activeCamera_, request, buffer);
tryCompleteRequest(request);
diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp
index 54dfb461..4268e314 100644
--- a/src/libcamera/request.cpp
+++ b/src/libcamera/request.cpp
@@ -238,7 +238,7 @@ bool Request::completeBuffer(Buffer *buffer)
buffer->request_ = nullptr;
- if (buffer->status() == Buffer::BufferCancelled)
+ if (buffer->metadata().status == FrameMetadata::FrameCancelled)
cancelled_ = true;
return !hasPendingBuffers();
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index 4551484c..d22655c6 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -1015,10 +1015,13 @@ int V4L2VideoDevice::queueBuffer(Buffer *buffer)
}
if (V4L2_TYPE_IS_OUTPUT(buf.type)) {
- buf.bytesused = buffer->bytesused_;
- buf.sequence = buffer->sequence_;
- buf.timestamp.tv_sec = buffer->timestamp_ / 1000000000;
- buf.timestamp.tv_usec = (buffer->timestamp_ / 1000) % 1000000;
+ const FrameMetadata &metadata = buffer->metadata();
+
+ if (!metadata.planes.empty())
+ buf.bytesused = metadata.planes[0].bytesused;
+ buf.sequence = metadata.sequence;
+ buf.timestamp.tv_sec = metadata.timestamp / 1000000000;
+ buf.timestamp.tv_usec = (metadata.timestamp / 1000) % 1000000;
}
LOG(V4L2, Debug) << "Queueing buffer " << buf.index;
@@ -1125,12 +1128,14 @@ Buffer *V4L2VideoDevice::dequeueBuffer()
fdEvent_->setEnabled(false);
buffer->index_ = buf.index;
- buffer->bytesused_ = buf.bytesused;
- buffer->timestamp_ = buf.timestamp.tv_sec * 1000000000ULL
- + buf.timestamp.tv_usec * 1000ULL;
- buffer->sequence_ = buf.sequence;
- buffer->status_ = buf.flags & V4L2_BUF_FLAG_ERROR
- ? Buffer::BufferError : Buffer::BufferSuccess;
+
+ buffer->metadata_.status = buf.flags & V4L2_BUF_FLAG_ERROR
+ ? FrameMetadata::FrameError
+ : FrameMetadata::FrameSuccess;
+ buffer->metadata_.sequence = buf.sequence;
+ buffer->metadata_.timestamp = buf.timestamp.tv_sec * 1000000000ULL
+ + buf.timestamp.tv_usec * 1000ULL;
+ buffer->metadata_.planes = { { buf.bytesused } };
return buffer;
}
diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
index 8b3d9923..ca3464ba 100644
--- a/src/qcam/main_window.cpp
+++ b/src/qcam/main_window.cpp
@@ -259,14 +259,15 @@ void MainWindow::requestComplete(Request *request)
framesCaptured_++;
Buffer *buffer = buffers.begin()->second;
+ const FrameMetadata &metadata = buffer->metadata();
- double fps = buffer->timestamp() - lastBufferTime_;
+ double fps = metadata.timestamp - lastBufferTime_;
fps = lastBufferTime_ && fps ? 1000000000.0 / fps : 0.0;
- lastBufferTime_ = buffer->timestamp();
+ lastBufferTime_ = metadata.timestamp;
- std::cout << "seq: " << std::setw(6) << std::setfill('0') << buffer->sequence()
- << " bytesused: " << buffer->bytesused()
- << " timestamp: " << buffer->timestamp()
+ std::cout << "seq: " << std::setw(6) << std::setfill('0') << metadata.sequence
+ << " bytesused: " << metadata.planes[0].bytesused
+ << " timestamp: " << metadata.timestamp
<< " fps: " << std::fixed << std::setprecision(2) << fps
<< std::endl;
@@ -306,7 +307,7 @@ int MainWindow::display(Buffer *buffer)
plane.fd.fd(), 0);
unsigned char *raw = static_cast<unsigned char *>(memory);
- viewfinder_->display(raw, buffer->bytesused());
+ viewfinder_->display(raw, buffer->metadata().planes[0].bytesused);
munmap(memory, plane.length);
diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp
index b6e0bb76..e4a03c41 100644
--- a/src/v4l2/v4l2_camera.cpp
+++ b/src/v4l2/v4l2_camera.cpp
@@ -17,9 +17,11 @@ using namespace libcamera;
LOG_DECLARE_CATEGORY(V4L2Compat);
V4L2FrameMetadata::V4L2FrameMetadata(Buffer *buffer)
- : index_(buffer->index()), bytesused_(buffer->bytesused()),
- timestamp_(buffer->timestamp()), sequence_(buffer->sequence()),
- status_(buffer->status())
+ : index_(buffer->index()),
+ bytesused_(buffer->metadata().planes[0].bytesused),
+ timestamp_(buffer->metadata().timestamp),
+ sequence_(buffer->metadata().sequence),
+ status_(buffer->metadata().status)
{
}
diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h
index f760316c..06eab0e1 100644
--- a/src/v4l2/v4l2_camera.h
+++ b/src/v4l2/v4l2_camera.h
@@ -31,7 +31,7 @@ public:
uint64_t timestamp() const { return timestamp_; }
unsigned int sequence() const { return sequence_; }
- Buffer::Status status() const { return status_; }
+ FrameMetadata::Status status() const { return status_; }
private:
int index_;
@@ -40,7 +40,7 @@ private:
uint64_t timestamp_;
unsigned int sequence_;
- Buffer::Status status_;
+ FrameMetadata::Status status_;
};
class V4L2Camera : public Object
diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index a84405a3..5158eac4 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -192,7 +192,7 @@ void V4L2CameraProxy::updateBuffers()
struct v4l2_buffer &buf = buffers_[fmd.index()];
switch (fmd.status()) {
- case Buffer::Status::BufferSuccess:
+ case FrameMetadata::FrameSuccess:
buf.bytesused = fmd.bytesused();
buf.field = V4L2_FIELD_NONE;
buf.timestamp.tv_sec = fmd.timestamp() / 1000000000;
@@ -201,7 +201,7 @@ void V4L2CameraProxy::updateBuffers()
buf.flags |= V4L2_BUF_FLAG_DONE;
break;
- case Buffer::Status::BufferError:
+ case FrameMetadata::FrameError:
buf.flags |= V4L2_BUF_FLAG_ERROR;
break;
default:
diff --git a/test/camera/buffer_import.cpp b/test/camera/buffer_import.cpp
index e5c010d8..3ba6ce96 100644
--- a/test/camera/buffer_import.cpp
+++ b/test/camera/buffer_import.cpp
@@ -275,7 +275,7 @@ public:
protected:
void bufferComplete(Request *request, Buffer *buffer)
{
- if (buffer->status() != Buffer::BufferSuccess)
+ if (buffer->metadata().status != FrameMetadata::FrameSuccess)
return;
unsigned int index = buffer->index();
diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp
index ca1ebe41..0d9ffc47 100644
--- a/test/camera/capture.cpp
+++ b/test/camera/capture.cpp
@@ -28,7 +28,7 @@ protected:
void bufferComplete(Request *request, Buffer *buffer)
{
- if (buffer->status() != Buffer::BufferSuccess)
+ if (buffer->metadata().status != FrameMetadata::FrameSuccess)
return;
completeBuffersCount_++;
diff --git a/test/v4l2_videodevice/buffer_sharing.cpp b/test/v4l2_videodevice/buffer_sharing.cpp
index 3a56862c..fe48b2e9 100644
--- a/test/v4l2_videodevice/buffer_sharing.cpp
+++ b/test/v4l2_videodevice/buffer_sharing.cpp
@@ -92,9 +92,11 @@ protected:
void captureBufferReady(Buffer *buffer)
{
+ const FrameMetadata &metadata = buffer->metadata();
+
std::cout << "Received capture buffer" << std::endl;
- if (buffer->status() != Buffer::BufferSuccess)
+ if (metadata.status != FrameMetadata::FrameSuccess)
return;
output_->queueBuffer(buffer);
@@ -103,9 +105,11 @@ protected:
void outputBufferReady(Buffer *buffer)
{
+ const FrameMetadata &metadata = buffer->metadata();
+
std::cout << "Received output buffer" << std::endl;
- if (buffer->status() != Buffer::BufferSuccess)
+ if (metadata.status != FrameMetadata::FrameSuccess)
return;
capture_->queueBuffer(buffer);