summaryrefslogtreecommitdiff
path: root/test
AgeCommit message (Expand)Author
2019-03-14test: camera: Add state machine testNiklas Söderlund
2019-03-14test: camera: Add capture testNiklas Söderlund
2019-03-14test: camera: Add setting of configuration testNiklas Söderlund
2019-03-14test: camera: Add read default configuration testNiklas Söderlund
2019-03-02test: v4l2_subdevice: Add ListFormat testJacopo Mondi
2019-03-01test: v4l2_device: Add format handling testJacopo Mondi
2019-03-01test: v4l2_subdevice: Add format handling testJacopo Mondi
2019-02-13test: v4l2_device: Provide buffer sharing testKieran Bingham
2019-02-13test: v4l2_device: release capture device resourcesKieran Bingham
2019-02-13test: v4l2_device: Rename dev_ to capture_Kieran Bingham
2019-02-13libcamera: v4l2_device: Simplify exportBuffers()Kieran Bingham
2019-02-13test: v4l2_device: capture_async: End test at 30 framesKieran Bingham
2019-02-13test: v4l2_device: Use VIVID capture streamKieran Bingham
2019-02-13libcamera: signal: Disconnect signal automatically on slot deletionLaurent Pinchart
2019-02-06test: v4l2_device: Provide asynchronous capture testKieran Bingham
2019-02-06test: v4l2_device: Add StreamOn/StreamOff testKieran Bingham
2019-02-06test: v4l2_device: Add request_buffers testKieran Bingham
2019-02-06test: v4l2_device: Use DeviceEnumerator to find a UVCVideoKieran Bingham
2019-01-24libcamera: device_enumerator: Reference-count MediaDevice instancesLaurent Pinchart
2019-01-23tests: event-dispatcher: Add processEvents() interruption testLaurent Pinchart
2019-01-23tests: Test event dispatcher interruption by signalLaurent Pinchart
2019-01-22libcamera: Global s/devnode/deviceNode renameJacopo Mondi
2019-01-22test: pipeline: IPU3: Add IPU3 pipeline testJacopo Mondi
2019-01-21libcamera: camera: Handle camera objects through shared pointersLaurent Pinchart
2019-01-21libcamera: camera_manager: Register cameras with the camera managerLaurent Pinchart
2019-01-17test: v4l2_device: Add test suite and initial testKieran Bingham
2019-01-17test: timer: Add a 32 bit wraparound testKieran Bingham
2019-01-17test: timer: Initialise all variablesKieran Bingham
2019-01-14test: media_device: Add link handling testJacopo Mondi
2019-01-14test: media_device: Make MediaDeviceTest a MediaDevicePrintTestJacopo Mondi
2019-01-14test: media_device: Convert to foreachKieran Bingham
2019-01-08test: Add event notifier testLaurent Pinchart
2019-01-08test: Add timer testLaurent Pinchart
2019-01-08test: Add signal/slot testLaurent Pinchart
2019-01-08test: Rename list test to list-camerasLaurent Pinchart
2019-01-08libcamera: camera_manager: Make the class a singletonLaurent Pinchart
2019-01-02test: Move include definitions to libtestKieran Bingham
2019-01-02test: Use foreach iterators to simplify definitionsKieran Bingham
2019-01-02test: media_device: Move test definitionKieran Bingham
2019-01-02libcamera: Remove libcamera classLaurent Pinchart
2019-01-01test: libtest: Return all non-zero init valuesKieran Bingham
2019-01-01test: libtest: Add test return codesKieran Bingham
2019-01-01test: Move test objects to libtestKieran Bingham
2018-12-31test: Add media device testJacopo Mondi
2018-12-31tests: add test to list all cameras in the systemNiklas Söderlund
2018-12-21tests: call the derived Test class cleanup() functionNiklas Söderlund
2018-12-21tests: Add a base Test classLaurent Pinchart
2018-12-06libcamera: Use the logger instead of coutLaurent Pinchart
2018-12-06Overhaul the directory structureLaurent Pinchart
2018-12-06Add boilerplate headers comments and include guardsLaurent Pinchart
n class="hl kwc">Type::Internal || type_ == Type::Mapped) { const PixelFormat outFormat = cameraDevice_->capabilities()->toPixelFormat(camera3Stream_->format); StreamConfiguration output = configuration(); output.pixelFormat = outFormat; output.size.width = camera3Stream_->width; output.size.height = camera3Stream_->height; switch (outFormat) { case formats::NV12: postProcessor_ = std::make_unique<PostProcessorYuv>(); break; case formats::MJPEG: postProcessor_ = std::make_unique<PostProcessorJpeg>(cameraDevice_); break; default: LOG(HAL, Error) << "Unsupported format: " << outFormat; return -EINVAL; } int ret = postProcessor_->configure(configuration(), output); if (ret) return ret; worker_ = std::make_unique<PostProcessorWorker>(postProcessor_.get()); postProcessor_->processComplete.connect( this, [&](Camera3RequestDescriptor::StreamBuffer *streamBuffer, PostProcessor::Status status) { Camera3RequestDescriptor::Status bufferStatus; if (status == PostProcessor::Status::Success) bufferStatus = Camera3RequestDescriptor::Status::Success; else bufferStatus = Camera3RequestDescriptor::Status::Error; cameraDevice_->streamProcessingComplete(streamBuffer, bufferStatus); }); worker_->start(); } if (type_ == Type::Internal) { allocator_ = std::make_unique<FrameBufferAllocator>(cameraDevice_->camera()); mutex_ = std::make_unique<Mutex>(); int ret = allocator_->allocate(stream()); if (ret < 0) return ret; /* Save a pointer to the reserved frame buffers */ for (const auto &frameBuffer : allocator_->buffers(stream())) buffers_.push_back(frameBuffer.get()); } camera3Stream_->max_buffers = configuration().bufferCount; return 0; } int CameraStream::waitFence(int fence) { /* * \todo The implementation here is copied from camera_worker.cpp * and both should be removed once libcamera is instrumented to handle * fences waiting in the core. * * \todo Better characterize the timeout. Currently equal to the one * used by the Rockchip Camera HAL on ChromeOS. */ constexpr unsigned int timeoutMs = 300; struct pollfd fds = { fence, POLLIN, 0 }; do { int ret = poll(&fds, 1, timeoutMs); if (ret == 0) return -ETIME; if (ret > 0) { if (fds.revents & (POLLERR | POLLNVAL)) return -EINVAL; return 0; } } while (errno == EINTR || errno == EAGAIN); return -errno; } int CameraStream::process(Camera3RequestDescriptor::StreamBuffer *streamBuffer) { ASSERT(type_ != Type::Direct); /* Handle waiting on fences on the destination buffer. */ if (streamBuffer->fence != -1) { int ret = waitFence(streamBuffer->fence); if (ret < 0) { LOG(HAL, Error) << "Failed waiting for fence: " << streamBuffer->fence << ": " << strerror(-ret); return ret; } ::close(streamBuffer->fence); streamBuffer->fence = -1; } const StreamConfiguration &output = configuration(); streamBuffer->dstBuffer = std::make_unique<CameraBuffer>( *streamBuffer->camera3Buffer, output.pixelFormat, output.size, PROT_READ | PROT_WRITE); if (!streamBuffer->dstBuffer->isValid()) { LOG(HAL, Error) << "Failed to create destination buffer"; return -EINVAL; } worker_->queueRequest(streamBuffer); return 0; } void CameraStream::flush() { if (!postProcessor_) return; worker_->flush(); } FrameBuffer *CameraStream::getBuffer() { if (!allocator_) return nullptr; MutexLocker locker(*mutex_); if (buffers_.empty()) { LOG(HAL, Error) << "Buffer underrun"; return nullptr; } FrameBuffer *buffer = buffers_.back(); buffers_.pop_back(); return buffer; } void CameraStream::putBuffer(FrameBuffer *buffer) { if (!allocator_) return; MutexLocker locker(*mutex_); buffers_.push_back(buffer); } CameraStream::PostProcessorWorker::PostProcessorWorker(PostProcessor *postProcessor) : postProcessor_(postProcessor) { } CameraStream::PostProcessorWorker::~PostProcessorWorker() { { MutexLocker lock(mutex_); state_ = State::Stopped; } cv_.notify_one(); wait(); } void CameraStream::PostProcessorWorker::start() { { MutexLocker lock(mutex_); ASSERT(state_ != State::Running); state_ = State::Running; } Thread::start(); } void CameraStream::PostProcessorWorker::queueRequest(Camera3RequestDescriptor::StreamBuffer *dest) { { MutexLocker lock(mutex_); ASSERT(state_ == State::Running); requests_.push(dest); } cv_.notify_one(); } void CameraStream::PostProcessorWorker::run() { MutexLocker locker(mutex_); while (1) { cv_.wait(locker, [&] { return state_ != State::Running || !requests_.empty(); }); if (state_ != State::Running) break; Camera3RequestDescriptor::StreamBuffer *streamBuffer = requests_.front(); requests_.pop(); locker.unlock(); postProcessor_->process(streamBuffer); locker.lock(); } if (state_ == State::Flushing) { std::queue<Camera3RequestDescriptor::StreamBuffer *> requests = std::move(requests_); locker.unlock(); while (!requests.empty()) { postProcessor_->processComplete.emit( requests.front(), PostProcessor::Status::Error); requests.pop(); } locker.lock(); state_ = State::Stopped; } } void CameraStream::PostProcessorWorker::flush() { MutexLocker lock(mutex_); state_ = State::Flushing; lock.unlock(); cv_.notify_one(); }