diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp index e7361dd463..38a78e070c 100644 --- a/camera/device/3.4/default/ExternalCameraDevice.cpp +++ b/camera/device/3.4/default/ExternalCameraDevice.cpp @@ -38,9 +38,8 @@ namespace { // Other formats to consider in the future: // * V4L2_PIX_FMT_YVU420 (== YV12) // * V4L2_PIX_FMT_YVYU (YVYU: can be converted to YV12 or other YUV420_888 formats) -const std::array kSupportedFourCCs {{ - V4L2_PIX_FMT_MJPEG -}}; // double braces required in C++11 +const std::array kSupportedFourCCs{ + {V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_Z16}}; // double braces required in C++11 constexpr int MAX_RETRY = 5; // Allow retry v4l2 open failures a few times. constexpr int OPEN_RETRY_SLEEP_US = 100000; // 100ms * MAX_RETRY = 0.5 seconds @@ -224,6 +223,13 @@ status_t ExternalCameraDevice::initCameraCharacteristics() { mCameraCharacteristics.clear(); return ret; } + + ret = initAvailableCapabilities(&mCameraCharacteristics); + if (ret != OK) { + ALOGE("%s: init available capabilities key failed: errorno %d", __FUNCTION__, ret); + mCameraCharacteristics.clear(); + return ret; + } } return OK; } @@ -237,6 +243,39 @@ do { \ } \ } while (0) +status_t ExternalCameraDevice::initAvailableCapabilities( + ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) { + + if (mSupportedFormats.empty()) { + ALOGE("%s: Supported formats list is empty", __FUNCTION__); + return UNKNOWN_ERROR; + } + + bool hasDepth = false; + bool hasColor = false; + for (const auto& fmt : mSupportedFormats) { + switch (fmt.fourcc) { + case V4L2_PIX_FMT_Z16: hasDepth = true; break; + case V4L2_PIX_FMT_MJPEG: hasColor = true; break; + default: ALOGW("%s: Unsupported format found", __FUNCTION__); + } + } + + std::vector availableCapabilities; + if (hasDepth) { + availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT); + } + if (hasColor) { + availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE); + } + if(!availableCapabilities.empty()) { + UPDATE(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, availableCapabilities.data(), + availableCapabilities.size()); + } + + return OK; +} + status_t ExternalCameraDevice::initDefaultCharsKeys( ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) { const uint8_t hardware_level = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL; @@ -323,12 +362,6 @@ status_t ExternalCameraDevice::initDefaultCharsKeys( &noiseReductionMode, 1); UPDATE(ANDROID_NOISE_REDUCTION_MODE, &noiseReductionMode, 1); - // android.request - const uint8_t availableCapabilities[] = { - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE}; - UPDATE(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, availableCapabilities, - ARRAY_SIZE(availableCapabilities)); - const int32_t partialResultCount = 1; UPDATE(ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &partialResultCount, 1); @@ -576,9 +609,11 @@ status_t ExternalCameraDevice::initCameraControlsCharsKeys(int, return OK; } -status_t ExternalCameraDevice::initOutputCharsKeys(int fd, - ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) { - initSupportedFormatsLocked(fd); +template +status_t ExternalCameraDevice::initOutputCharskeysByFormat( + ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata, + uint32_t fourcc, const std::array& halFormats, + int streamConfigTag, int streamConfiguration, int minFrameDuration, int stallDuration) { if (mSupportedFormats.empty()) { ALOGE("%s: Init supported format list failed", __FUNCTION__); return UNKNOWN_ERROR; @@ -587,22 +622,17 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd, std::vector streamConfigurations; std::vector minFrameDurations; std::vector stallDurations; - int32_t maxFps = std::numeric_limits::min(); - int32_t minFps = std::numeric_limits::max(); - std::set framerates; - - std::array halFormats{{ - HAL_PIXEL_FORMAT_BLOB, - HAL_PIXEL_FORMAT_YCbCr_420_888, - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED}}; for (const auto& supportedFormat : mSupportedFormats) { + if (supportedFormat.fourcc != fourcc) { + // Skip 4CCs not meant for the halFormats + continue; + } for (const auto& format : halFormats) { streamConfigurations.push_back(format); streamConfigurations.push_back(supportedFormat.width); streamConfigurations.push_back(supportedFormat.height); - streamConfigurations.push_back( - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT); + streamConfigurations.push_back(streamConfigTag); } int64_t minFrameDuration = std::numeric_limits::max(); @@ -614,14 +644,6 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd, if (frameDuration < minFrameDuration) { minFrameDuration = frameDuration; } - int32_t frameRateInt = static_cast(fr.getDouble()); - if (minFps > frameRateInt) { - minFps = frameRateInt; - } - if (maxFps < frameRateInt) { - maxFps = frameRateInt; - } - framerates.insert(frameRateInt); } for (const auto& format : halFormats) { @@ -645,6 +667,30 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd, } } + UPDATE(streamConfiguration, streamConfigurations.data(), streamConfigurations.size()); + + UPDATE(minFrameDuration, minFrameDurations.data(), minFrameDurations.size()); + + UPDATE(stallDuration, stallDurations.data(), stallDurations.size()); + + return true; +} + +bool ExternalCameraDevice::calculateMinFps( + ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) { + std::set framerates; + int32_t minFps = std::numeric_limits::max(); + + for (const auto& supportedFormat : mSupportedFormats) { + for (const auto& fr : supportedFormat.frameRates) { + int32_t frameRateInt = static_cast(fr.getDouble()); + if (minFps > frameRateInt) { + minFps = frameRateInt; + } + framerates.insert(frameRateInt); + } + } + std::vector fpsRanges; // FPS ranges for (const auto& framerate : framerates) { @@ -658,17 +704,60 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd, UPDATE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fpsRanges.data(), fpsRanges.size()); - UPDATE(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, - streamConfigurations.data(), streamConfigurations.size()); - - UPDATE(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, - minFrameDurations.data(), minFrameDurations.size()); - - UPDATE(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, stallDurations.data(), - stallDurations.size()); - UPDATE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, &maxFrameDuration, 1); + return true; +} + +status_t ExternalCameraDevice::initOutputCharsKeys( + int fd, ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) { + initSupportedFormatsLocked(fd); + if (mSupportedFormats.empty()) { + ALOGE("%s: Init supported format list failed", __FUNCTION__); + return UNKNOWN_ERROR; + } + + bool hasDepth = false; + bool hasColor = false; + + // For V4L2_PIX_FMT_Z16 + std::array halDepthFormats{{HAL_PIXEL_FORMAT_Y16}}; + // For V4L2_PIX_FMT_MJPEG + std::array halFormats{{HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_YCbCr_420_888, + HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED}}; + + for (const auto& supportedFormat : mSupportedFormats) { + switch (supportedFormat.fourcc) { + case V4L2_PIX_FMT_Z16: + hasDepth = true; + break; + case V4L2_PIX_FMT_MJPEG: + hasColor = true; + break; + default: + ALOGW("%s: format %c%c%c%c is not supported!", __FUNCTION__, + supportedFormat.fourcc & 0xFF, (supportedFormat.fourcc >> 8) & 0xFF, + (supportedFormat.fourcc >> 16) & 0xFF, (supportedFormat.fourcc >> 24) & 0xFF); + } + } + + if (hasDepth) { + initOutputCharskeysByFormat(metadata, V4L2_PIX_FMT_Z16, halDepthFormats, + ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT, + ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, + ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS, + ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS); + } + if (hasColor) { + initOutputCharskeysByFormat(metadata, V4L2_PIX_FMT_MJPEG, halFormats, + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, + ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, + ANDROID_SCALER_AVAILABLE_STALL_DURATIONS); + } + + calculateMinFps(metadata); + SupportedV4L2Format maximumFormat {.width = 0, .height = 0}; for (const auto& supportedFormat : mSupportedFormats) { if (supportedFormat.width >= maximumFormat.width && @@ -790,11 +879,12 @@ void ExternalCameraDevice::trimSupportedFormats( sortedFmts = out; } -std::vector -ExternalCameraDevice::getCandidateSupportedFormatsLocked( - int fd, CroppingType cropType, - const std::vector& fpsLimits, - const Size& minStreamSize) { +std::vector ExternalCameraDevice::getCandidateSupportedFormatsLocked( + int fd, CroppingType cropType, + const std::vector& fpsLimits, + const std::vector& depthFpsLimits, + const Size& minStreamSize, + bool depthEnabled) { std::vector outFmts; struct v4l2_fmtdesc fmtdesc { .index = 0, @@ -840,28 +930,10 @@ ExternalCameraDevice::getCandidateSupportedFormatsLocked( .fourcc = fmtdesc.pixelformat }; - double fpsUpperBound = -1.0; - for (const auto& limit : fpsLimits) { - if (cropType == VERTICAL) { - if (format.width <= limit.size.width) { - fpsUpperBound = limit.fpsUpperBound; - break; - } - } else { // HORIZONTAL - if (format.height <= limit.size.height) { - fpsUpperBound = limit.fpsUpperBound; - break; - } - } - - } - if (fpsUpperBound < 0.f) { - continue; - } - - getFrameRateList(fd, fpsUpperBound, &format); - if (!format.frameRates.empty()) { - outFmts.push_back(format); + if (format.fourcc == V4L2_PIX_FMT_Z16 && depthEnabled) { + updateFpsBounds(fd, cropType, depthFpsLimits, format, outFmts); + } else { + updateFpsBounds(fd, cropType, fpsLimits, format, outFmts); } } } @@ -873,12 +945,39 @@ ExternalCameraDevice::getCandidateSupportedFormatsLocked( return outFmts; } -void ExternalCameraDevice::initSupportedFormatsLocked(int fd) { +void ExternalCameraDevice::updateFpsBounds( + int fd, CroppingType cropType, + const std::vector& fpsLimits, SupportedV4L2Format format, + std::vector& outFmts) { + double fpsUpperBound = -1.0; + for (const auto& limit : fpsLimits) { + if (cropType == VERTICAL) { + if (format.width <= limit.size.width) { + fpsUpperBound = limit.fpsUpperBound; + break; + } + } else { // HORIZONTAL + if (format.height <= limit.size.height) { + fpsUpperBound = limit.fpsUpperBound; + break; + } + } + } + if (fpsUpperBound < 0.f) { + return; + } - std::vector horizontalFmts = - getCandidateSupportedFormatsLocked(fd, HORIZONTAL, mCfg.fpsLimits, mCfg.minStreamSize); - std::vector verticalFmts = - getCandidateSupportedFormatsLocked(fd, VERTICAL, mCfg.fpsLimits, mCfg.minStreamSize); + getFrameRateList(fd, fpsUpperBound, &format); + if (!format.frameRates.empty()) { + outFmts.push_back(format); + } +} + +void ExternalCameraDevice::initSupportedFormatsLocked(int fd) { + std::vector horizontalFmts = getCandidateSupportedFormatsLocked( + fd, HORIZONTAL, mCfg.fpsLimits, mCfg.depthFpsLimits, mCfg.minStreamSize, mCfg.depthEnabled); + std::vector verticalFmts = getCandidateSupportedFormatsLocked( + fd, VERTICAL, mCfg.fpsLimits, mCfg.depthFpsLimits, mCfg.minStreamSize, mCfg.depthEnabled); size_t horiSize = horizontalFmts.size(); size_t vertSize = verticalFmts.size(); diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp index dce40ff285..a12d8e4243 100644 --- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp +++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp @@ -1724,7 +1724,7 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() { return false; }; - if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG) { + if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG && req->frameIn->mFourcc != V4L2_PIX_FMT_Z16) { return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__, req->frameIn->mFourcc & 0xFF, (req->frameIn->mFourcc >> 8) & 0xFF, @@ -1743,29 +1743,26 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() { } // TODO: in some special case maybe we can decode jpg directly to gralloc output? - ATRACE_BEGIN("MJPGtoI420"); - int res = libyuv::MJPGToI420( - inData, inDataSize, - static_cast(mYu12FrameLayout.y), - mYu12FrameLayout.yStride, - static_cast(mYu12FrameLayout.cb), - mYu12FrameLayout.cStride, - static_cast(mYu12FrameLayout.cr), - mYu12FrameLayout.cStride, - mYu12Frame->mWidth, mYu12Frame->mHeight, - mYu12Frame->mWidth, mYu12Frame->mHeight); - ATRACE_END(); + if (req->frameIn->mFourcc == V4L2_PIX_FMT_MJPEG) { + ATRACE_BEGIN("MJPGtoI420"); + int res = libyuv::MJPGToI420( + inData, inDataSize, static_cast(mYu12FrameLayout.y), mYu12FrameLayout.yStride, + static_cast(mYu12FrameLayout.cb), mYu12FrameLayout.cStride, + static_cast(mYu12FrameLayout.cr), mYu12FrameLayout.cStride, + mYu12Frame->mWidth, mYu12Frame->mHeight, mYu12Frame->mWidth, mYu12Frame->mHeight); + ATRACE_END(); - if (res != 0) { - // For some webcam, the first few V4L2 frames might be malformed... - ALOGE("%s: Convert V4L2 frame to YU12 failed! res %d", __FUNCTION__, res); - lk.unlock(); - Status st = parent->processCaptureRequestError(req); - if (st != Status::OK) { - return onDeviceError("%s: failed to process capture request error!", __FUNCTION__); + if (res != 0) { + // For some webcam, the first few V4L2 frames might be malformed... + ALOGE("%s: Convert V4L2 frame to YU12 failed! res %d", __FUNCTION__, res); + lk.unlock(); + Status st = parent->processCaptureRequestError(req); + if (st != Status::OK) { + return onDeviceError("%s: failed to process capture request error!", __FUNCTION__); + } + signalRequestDone(); + return true; } - signalRequestDone(); - return true; } ALOGV("%s processing new request", __FUNCTION__); @@ -1796,6 +1793,16 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() { __FUNCTION__, ret); } } break; + case PixelFormat::Y16: { + void* outLayout = sHandleImporter.lock(*(halBuf.bufPtr), halBuf.usage, inDataSize); + + std::memcpy(outLayout, inData, inDataSize); + + int relFence = sHandleImporter.unlock(*(halBuf.bufPtr)); + if (relFence >= 0) { + halBuf.acquireFence = relFence; + } + } break; case PixelFormat::YCBCR_420_888: case PixelFormat::YV12: { IMapper::Rect outRect {0, 0, @@ -2063,11 +2070,6 @@ bool ExternalCameraDeviceSession::isSupported(const Stream& stream) { return false; } - if (ds & Dataspace::DEPTH) { - ALOGI("%s: does not support depth output", __FUNCTION__); - return false; - } - switch (fmt) { case PixelFormat::BLOB: if (ds != static_cast(Dataspace::V0_JFIF)) { @@ -2081,6 +2083,16 @@ bool ExternalCameraDeviceSession::isSupported(const Stream& stream) { // TODO: check what dataspace we can support here. // intentional no-ops. break; + case PixelFormat::Y16: + if (!mCfg.depthEnabled) { + ALOGI("%s: Depth is not Enabled", __FUNCTION__); + return false; + } + if (!(ds & Dataspace::DEPTH)) { + ALOGI("%s: Y16 supports only dataSpace DEPTH", __FUNCTION__); + return false; + } + break; default: ALOGI("%s: does not support format %x", __FUNCTION__, fmt); return false; @@ -2609,6 +2621,7 @@ Status ExternalCameraDeviceSession::configureStreams( case PixelFormat::BLOB: case PixelFormat::YCBCR_420_888: case PixelFormat::YV12: // Used by SurfaceTexture + case PixelFormat::Y16: // No override out->streams[i].v3_2.overrideFormat = config.streams[i].format; break; diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp index 680c95ad3b..a07c62936f 100644 --- a/camera/device/3.4/default/ExternalCameraUtils.cpp +++ b/camera/device/3.4/default/ExternalCameraUtils.cpp @@ -21,7 +21,6 @@ #include #include #include "ExternalCameraUtils.h" -#include "tinyxml2.h" // XML parsing namespace android { namespace hardware { @@ -243,28 +242,28 @@ ExternalCameraConfig ExternalCameraConfig::loadFromCfg(const char* cfgPath) { if (fpsList == nullptr) { ALOGI("%s: no fps list specified", __FUNCTION__); } else { - std::vector limits; - XMLElement *row = fpsList->FirstChildElement("Limit"); - while (row != nullptr) { - FpsLimitation prevLimit {{0, 0}, 1000.0}; - FpsLimitation limit; - limit.size = { - row->UnsignedAttribute("width", /*Default*/0), - row->UnsignedAttribute("height", /*Default*/0)}; - limit.fpsUpperBound = row->DoubleAttribute("fpsBound", /*Default*/1000.0); - if (limit.size.width <= prevLimit.size.width || - limit.size.height <= prevLimit.size.height || - limit.fpsUpperBound >= prevLimit.fpsUpperBound) { - ALOGE("%s: FPS limit list must have increasing size and decreasing fps!" - " Prev %dx%d@%f, Current %dx%d@%f", __FUNCTION__, - prevLimit.size.width, prevLimit.size.height, prevLimit.fpsUpperBound, - limit.size.width, limit.size.height, limit.fpsUpperBound); + if (!updateFpsList(fpsList, ret.fpsLimits)) { + return ret; + } + } + + XMLElement *depth = deviceCfg->FirstChildElement("Depth16Supported"); + if (depth == nullptr) { + ret.depthEnabled = false; + ALOGI("%s: depth output is not enabled", __FUNCTION__); + } else { + ret.depthEnabled = depth->BoolAttribute("enabled", false); + } + + if(ret.depthEnabled) { + XMLElement *depthFpsList = deviceCfg->FirstChildElement("DepthFpsList"); + if (depthFpsList == nullptr) { + ALOGW("%s: no depth fps list specified", __FUNCTION__); + } else { + if(!updateFpsList(depthFpsList, ret.depthFpsLimits)) { return ret; } - limits.push_back(limit); - row = row->NextSiblingElement("Limit"); } - ret.fpsLimits = limits; } XMLElement *minStreamSize = deviceCfg->FirstChildElement("MinimumStreamSize"); @@ -284,15 +283,48 @@ ExternalCameraConfig ExternalCameraConfig::loadFromCfg(const char* cfgPath) { ALOGI("%s: fpsLimitList: %dx%d@%f", __FUNCTION__, limit.size.width, limit.size.height, limit.fpsUpperBound); } + for (const auto& limit : ret.depthFpsLimits) { + ALOGI("%s: depthFpsLimitList: %dx%d@%f", __FUNCTION__, limit.size.width, limit.size.height, + limit.fpsUpperBound); + } ALOGI("%s: minStreamSize: %dx%d" , __FUNCTION__, ret.minStreamSize.width, ret.minStreamSize.height); return ret; } +bool ExternalCameraConfig::updateFpsList(tinyxml2::XMLElement* fpsList, + std::vector& fpsLimits) { + using namespace tinyxml2; + std::vector limits; + XMLElement* row = fpsList->FirstChildElement("Limit"); + while (row != nullptr) { + FpsLimitation prevLimit{{0, 0}, 1000.0}; + FpsLimitation limit; + limit.size = {row->UnsignedAttribute("width", /*Default*/ 0), + row->UnsignedAttribute("height", /*Default*/ 0)}; + limit.fpsUpperBound = row->DoubleAttribute("fpsBound", /*Default*/ 1000.0); + if (limit.size.width <= prevLimit.size.width || + limit.size.height <= prevLimit.size.height || + limit.fpsUpperBound >= prevLimit.fpsUpperBound) { + ALOGE( + "%s: FPS limit list must have increasing size and decreasing fps!" + " Prev %dx%d@%f, Current %dx%d@%f", + __FUNCTION__, prevLimit.size.width, prevLimit.size.height, prevLimit.fpsUpperBound, + limit.size.width, limit.size.height, limit.fpsUpperBound); + return false; + } + limits.push_back(limit); + row = row->NextSiblingElement("Limit"); + } + fpsLimits = limits; + return true; +} + ExternalCameraConfig::ExternalCameraConfig() : maxJpegBufSize(kDefaultJpegBufSize), numVideoBuffers(kDefaultNumVideoBuffer), - numStillBuffers(kDefaultNumStillBuffer) { + numStillBuffers(kDefaultNumStillBuffer), + depthEnabled(false) { fpsLimits.push_back({/*Size*/{ 640, 480}, /*FPS upper bound*/30.0}); fpsLimits.push_back({/*Size*/{1280, 720}, /*FPS upper bound*/7.5}); fpsLimits.push_back({/*Size*/{1920, 1080}, /*FPS upper bound*/5.0}); diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h index ff0cfb301e..28b9cef7af 100644 --- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h +++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h @@ -82,6 +82,9 @@ protected: void initSupportedFormatsLocked(int fd); status_t initCameraCharacteristics(); + // Init available capabilities keys + status_t initAvailableCapabilities( + ::android::hardware::camera::common::V1_0::helper::CameraMetadata*); // Init non-device dependent keys status_t initDefaultCharsKeys(::android::hardware::camera::common::V1_0::helper::CameraMetadata*); // Init camera control chars keys. Caller still owns fd @@ -91,13 +94,30 @@ protected: status_t initOutputCharsKeys(int fd, ::android::hardware::camera::common::V1_0::helper::CameraMetadata*); + // Helper function for initOutputCharskeys + template + status_t initOutputCharskeysByFormat( + ::android::hardware::camera::common::V1_0::helper::CameraMetadata*, + uint32_t fourcc, const std::array& formats, + int scaler_stream_config_tag, + int stream_configuration, int min_frame_duration, int stall_duration); + + bool calculateMinFps(::android::hardware::camera::common::V1_0::helper::CameraMetadata*); + static void getFrameRateList(int fd, double fpsUpperBound, SupportedV4L2Format* format); + static void updateFpsBounds(int fd, CroppingType cropType, + const std::vector& fpsLimits, + SupportedV4L2Format format, + std::vector& outFmts); + // Get candidate supported formats list of input cropping type. static std::vector getCandidateSupportedFormatsLocked( int fd, CroppingType cropType, const std::vector& fpsLimits, - const Size& minStreamSize); + const std::vector& depthFpsLimits, + const Size& minStreamSize, + bool depthEnabled); // Trim supported format list by the cropping type. Also sort output formats by width/height static void trimSupportedFormats(CroppingType cropType, /*inout*/std::vector* pFmts); diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h index 5754ccbec3..f696057068 100644 --- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h +++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h @@ -17,12 +17,13 @@ #ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_EXTCAMUTIL_H #define ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_EXTCAMUTIL_H -#include -#include "utils/LightRefBase.h" -#include -#include -#include #include +#include +#include +#include +#include +#include "tinyxml2.h" // XML parsing +#include "utils/LightRefBase.h" using android::hardware::graphics::mapper::V2_0::IMapper; using android::hardware::graphics::mapper::V2_0::YCbCrLayout; @@ -71,17 +72,22 @@ struct ExternalCameraConfig { // Size of v4l2 buffer queue when streaming > kMaxVideoSize uint32_t numStillBuffers; + // Indication that the device connected supports depth output + bool depthEnabled; + struct FpsLimitation { Size size; double fpsUpperBound; }; std::vector fpsLimits; + std::vector depthFpsLimits; // Minimum output stream size Size minStreamSize; private: ExternalCameraConfig(); + static bool updateFpsList(tinyxml2::XMLElement* fpsList, std::vector& fpsLimits); }; } // common