summaryrefslogtreecommitdiff
path: root/test/media_device
AgeCommit message (Expand)Author
2020-10-23libcamera: Drop unneeded empty default constructors and destructorsLaurent Pinchart
2020-10-20test: Omit extra semicolonsHirokazu Honda
2020-05-16libcamera: Move internal headers to include/libcamera/internal/Laurent Pinchart
2020-05-13licenses: License all meson files under CC0-1.0Laurent Pinchart
2019-11-18libcamera: Remove space between empty curly bracketsLaurent Pinchart
2019-10-23libcamera: Standardise on C compatibility headersLaurent Pinchart
2019-05-23meson: Create and use a dependency for libcamera and its headersLaurent Pinchart
2019-05-23meson: Fix coding style in meson.build filesLaurent Pinchart
2019-05-17test: media_device: Add test for acquire() and release()Niklas Söderlund
2019-05-17test: media_device: Create a common MediaDeviceTest base classNiklas Söderlund
2019-05-17libcamera: media_device: Handle media device fd in acquire() and release()Niklas Söderlund
2019-05-17libcamera: media_device: Open and close media device inside populate()Niklas Söderlund
2019-05-17libcamera: Always check return value of MediaDevice::acquire()Niklas Söderlund
2019-01-24libcamera: device_enumerator: Reference-count MediaDevice instancesLaurent Pinchart
2019-01-22libcamera: Global s/devnode/deviceNode renameJacopo Mondi
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-02test: media_device: Move test definitionKieran Bingham
2019-01-01test: Move test objects to libtestKieran Bingham
2018-12-31test: Add media device testJacopo Mondi
V) int PostProcessorYuv::configure(const StreamConfiguration &inCfg, const StreamConfiguration &outCfg) { if (inCfg.pixelFormat != outCfg.pixelFormat) { LOG(YUV, Error) << "Pixel format conversion is not supported" << " (from " << inCfg.pixelFormat.toString() << " to " << outCfg.pixelFormat.toString() << ")"; return -EINVAL; } if (inCfg.size < outCfg.size) { LOG(YUV, Error) << "Up-scaling is not supported" << " (from " << inCfg.size.toString() << " to " << outCfg.size.toString() << ")"; return -EINVAL; } if (inCfg.pixelFormat != formats::NV12) { LOG(YUV, Error) << "Unsupported format " << inCfg.pixelFormat << " (only NV12 is supported)"; return -EINVAL; } calculateLengths(inCfg, outCfg); return 0; } void PostProcessorYuv::process(Camera3RequestDescriptor::StreamBuffer *streamBuffer) { const FrameBuffer &source = *streamBuffer->srcBuffer; CameraBuffer *destination = streamBuffer->dstBuffer.get(); if (!isValidBuffers(source, *destination)) { processComplete.emit(streamBuffer, PostProcessor::Status::Error); return; } const MappedFrameBuffer sourceMapped(&source, MappedFrameBuffer::MapFlag::Read); if (!sourceMapped.isValid()) { LOG(YUV, Error) << "Failed to mmap camera frame buffer"; processComplete.emit(streamBuffer, PostProcessor::Status::Error); return; } int ret = libyuv::NV12Scale(sourceMapped.planes()[0].data(), sourceStride_[0], sourceMapped.planes()[1].data(), sourceStride_[1], sourceSize_.width, sourceSize_.height, destination->plane(0).data(), destinationStride_[0], destination->plane(1).data(), destinationStride_[1], destinationSize_.width, destinationSize_.height, libyuv::FilterMode::kFilterBilinear); if (ret) { LOG(YUV, Error) << "Failed NV12 scaling: " << ret; processComplete.emit(streamBuffer, PostProcessor::Status::Error); return; } processComplete.emit(streamBuffer, PostProcessor::Status::Success); } bool PostProcessorYuv::isValidBuffers(const FrameBuffer &source, const CameraBuffer &destination) const { if (source.planes().size() != 2) { LOG(YUV, Error) << "Invalid number of source planes: " << source.planes().size(); return false; } if (destination.numPlanes() != 2) { LOG(YUV, Error) << "Invalid number of destination planes: " << destination.numPlanes(); return false; } if (source.planes()[0].length < sourceLength_[0] || source.planes()[1].length < sourceLength_[1]) { LOG(YUV, Error) << "The source planes lengths are too small, actual size: {" << source.planes()[0].length << ", " << source.planes()[1].length << "}, expected size: {" << sourceLength_[0] << ", " << sourceLength_[1] << "}"; return false; } if (destination.plane(0).size() < destinationLength_[0] || destination.plane(1).size() < destinationLength_[1]) { LOG(YUV, Error) << "The destination planes lengths are too small, actual size: {" << destination.plane(0).size() << ", " << destination.plane(1).size() << "}, expected size: {" << sourceLength_[0] << ", " << sourceLength_[1] << "}"; return false; } return true; } void PostProcessorYuv::calculateLengths(const StreamConfiguration &inCfg, const StreamConfiguration &outCfg) { sourceSize_ = inCfg.size; destinationSize_ = outCfg.size; const PixelFormatInfo &nv12Info = PixelFormatInfo::info(formats::NV12); for (unsigned int i = 0; i < 2; i++) { sourceStride_[i] = inCfg.stride; destinationStride_[i] = nv12Info.stride(destinationSize_.width, i, 1); sourceLength_[i] = nv12Info.planeSize(sourceSize_.height, i, sourceStride_[i]); destinationLength_[i] = nv12Info.planeSize(destinationSize_.height, i, destinationStride_[i]); } }