diff --git a/config/linux/ipu6ep/sensors/isx031.xml b/config/linux/ipu6ep/sensors/isx031.xml index d7525f52..2dee4812 100644 --- a/config/linux/ipu6ep/sensors/isx031.xml +++ b/config/linux/ipu6ep/sensors/isx031.xml @@ -78,6 +78,7 @@ + @@ -144,6 +145,7 @@ + @@ -210,6 +212,7 @@ + @@ -276,6 +279,7 @@ + @@ -342,6 +346,7 @@ + @@ -408,6 +413,7 @@ + @@ -474,6 +480,7 @@ + @@ -540,6 +547,7 @@ + - \ No newline at end of file + diff --git a/config/linux/ipu6epmtl/libcamhal_profile.xml b/config/linux/ipu6epmtl/libcamhal_profile.xml index e51ac861..75329060 100644 --- a/config/linux/ipu6epmtl/libcamhal_profile.xml +++ b/config/linux/ipu6epmtl/libcamhal_profile.xml @@ -22,6 +22,7 @@ + imx390,imx390-1-0,imx390-2-0,imx390-3-0,imx390-4-0,imx390-5-4,imx390-6-4,ar0234-1-0,ar0234-2-4, + external_source,ar0234_usb,lt6911uxc,lt6911uxe-1-0,lt6911uxe-2-4"/> diff --git a/config/linux/ipu6epmtl/sensors/imx390-1.xml b/config/linux/ipu6epmtl/sensors/imx390-1.xml new file mode 100644 index 00000000..dfd60042 --- /dev/null +++ b/config/linux/ipu6epmtl/sensors/imx390-1.xml @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/linux/ipu6epmtl/sensors/imx390-2.xml b/config/linux/ipu6epmtl/sensors/imx390-2.xml new file mode 100644 index 00000000..c2758cb2 --- /dev/null +++ b/config/linux/ipu6epmtl/sensors/imx390-2.xml @@ -0,0 +1,281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/linux/ipu6epmtl/sensors/imx390-3.xml b/config/linux/ipu6epmtl/sensors/imx390-3.xml new file mode 100644 index 00000000..2f401b62 --- /dev/null +++ b/config/linux/ipu6epmtl/sensors/imx390-3.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/linux/ipu6epmtl/sensors/imx390-4.xml b/config/linux/ipu6epmtl/sensors/imx390-4.xml new file mode 100644 index 00000000..da20ad90 --- /dev/null +++ b/config/linux/ipu6epmtl/sensors/imx390-4.xml @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/linux/ipu6epmtl/sensors/imx390-5.xml b/config/linux/ipu6epmtl/sensors/imx390-5.xml new file mode 100644 index 00000000..5e1ede98 --- /dev/null +++ b/config/linux/ipu6epmtl/sensors/imx390-5.xml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/linux/ipu6epmtl/sensors/imx390-6.xml b/config/linux/ipu6epmtl/sensors/imx390-6.xml new file mode 100644 index 00000000..8cbab093 --- /dev/null +++ b/config/linux/ipu6epmtl/sensors/imx390-6.xml @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h index 94a89b63..8f544245 100644 --- a/include/linux/v4l2-subdev.h +++ b/include/linux/v4l2-subdev.h @@ -129,6 +129,8 @@ struct v4l2_subdev_selection { #define V4L2_SUBDEV_ROUTE_FL_ACTIVE (1 << 0) #define V4L2_SUBDEV_ROUTE_FL_IMMUTABLE (1 << 1) #define V4L2_SUBDEV_ROUTE_FL_SOURCE (1 << 2) +#define VIDIOC_SUBDEV_G_CLIENT_CAP _IOR('V', 101, struct v4l2_subdev_client_capability) +#define VIDIOC_SUBDEV_S_CLIENT_CAP _IOWR('V', 102, struct v4l2_subdev_client_capability) /** * struct v4l2_subdev_route - A signal route inside a subdev * @sink_pad: the sink pad @@ -158,14 +160,47 @@ struct v4l2_subdev_route { }; /** - * struct v4l2_subdev_routing - Routing information - * @routes: the routes array - * @num_routes: the total number of routes in the routes array + * struct v4l2_subdev_routing - Subdev routing information + * + * @which: configuration type (from enum v4l2_subdev_format_whence) + * @len_routes: the length of the routes array, in routes; set by the user, not + * modified by the kernel + * @routes: pointer to the routes array + * @num_routes: the total number of routes, possibly more than fits in the + * routes array + * @reserved: drivers and applications must zero this array */ struct v4l2_subdev_routing { - struct v4l2_subdev_route *routes; + __u32 which; + __u32 len_routes; + __u64 routes; __u32 num_routes; - __u32 reserved[5]; + __u32 reserved[11]; +}; + +/* + * The client is aware of streams. Setting this flag enables the use of 'stream' + * fields (referring to the stream number) with various ioctls. If this is not + * set (which is the default), the 'stream' fields will be forced to 0 by the + * kernel. + */ +#define V4L2_SUBDEV_CLIENT_CAP_STREAMS (1ULL << 0) + +/* + * The client is aware of the struct v4l2_subdev_frame_interval which field. If + * this is not set (which is the default), the which field is forced to + * V4L2_SUBDEV_FORMAT_ACTIVE by the kernel. + */ +#define V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH (1ULL << 1) + +/** + * struct v4l2_subdev_client_capability - Capabilities of the client accessing + * the subdev + * + * @capabilities: A bitmask of V4L2_SUBDEV_CLIENT_CAP_* flags. + */ +struct v4l2_subdev_client_capability { + __u64 capabilities; }; #endif diff --git a/modules/memory/chrome/Camera3Buffer.cpp b/modules/memory/chrome/Camera3Buffer.cpp index 72f23866..3e2fd2b2 100644 --- a/modules/memory/chrome/Camera3Buffer.cpp +++ b/modules/memory/chrome/Camera3Buffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2023 Intel Corporation + * Copyright (C) 2013-2024 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,9 @@ #include #include +#include +#include +#include #include #include "Camera3Stream.h" @@ -406,8 +409,19 @@ void Camera3Buffer::dumpImage(const void* data, int frameNumber, const int size, std::string fileName(gDumpPath); fileName += "dump_" + std::to_string(width) + "x" + std::to_string(height) + "_frame#" + - std::to_string(count) + "_req#" + std::to_string(frameNumber) + "." + - CameraUtils::format2string(format).c_str(); + std::to_string(count) + "_req#" + std::to_string(frameNumber); + + struct timeval tv; + gettimeofday(&tv, nullptr); + time_t nowtime = tv.tv_sec; + struct tm targetTm; + struct tm* nowtm = localtime_r(&nowtime, &targetTm); + if (nowtm) { + fileName += "_time#" + std::to_string(nowtm->tm_mday) + ":" + std::to_string(nowtm->tm_min) + + ":" + std::to_string(nowtm->tm_sec) + ":" + std::to_string(tv.tv_usec / 1000); + } + + fileName += "." + std::string(CameraUtils::format2string(format).c_str()); LOG2("%s filename is %s", __func__, fileName.data()); FILE* fp = fopen(fileName.data(), "w+"); diff --git a/modules/v4l2/v4l2_subdevice.cc b/modules/v4l2/v4l2_subdevice.cc index 2d93b1d4..c4d13591 100644 --- a/modules/v4l2/v4l2_subdevice.cc +++ b/modules/v4l2/v4l2_subdevice.cc @@ -46,11 +46,19 @@ V4L2Subdevice::~V4L2Subdevice() { } int V4L2Subdevice::Open(int flags) { + struct v4l2_subdev_client_capability clientcap = {}; + LOG1("@%s", __func__); int status = V4L2Device::Open(flags); if (status == 0) state_ = SubdevState::OPEN; - return status; + + clientcap.capabilities = V4L2_SUBDEV_CLIENT_CAP_STREAMS; + status = ioctl(fd_, VIDIOC_SUBDEV_S_CLIENT_CAP, &clientcap); + if (status < 0) + LOG1("Failed to set client capabilities %s", strerror(errno)); + + return 0; } int V4L2Subdevice::Close() { @@ -142,7 +150,11 @@ int V4L2Subdevice::SetRouting(v4l2_subdev_route* routes, uint32_t numRoutes) { return -EINVAL; } - v4l2_subdev_routing r = {routes, numRoutes}; + v4l2_subdev_routing r = {}; + r.which = V4L2_SUBDEV_FORMAT_ACTIVE; + r.len_routes = numRoutes; + r.num_routes = numRoutes; + r.routes = reinterpret_cast(routes); int ret = ::ioctl(fd_, VIDIOC_SUBDEV_S_ROUTING, &r); if (ret < 0) { @@ -162,7 +174,11 @@ int V4L2Subdevice::GetRouting(v4l2_subdev_route* routes, uint32_t* numRoutes) { return -EINVAL; } - v4l2_subdev_routing r = {routes, *numRoutes}; + v4l2_subdev_routing r = {}; + r.which = V4L2_SUBDEV_FORMAT_ACTIVE; + r.len_routes = *numRoutes; + r.num_routes = *numRoutes; + r.routes = reinterpret_cast(routes); int ret = ::ioctl(fd_, VIDIOC_SUBDEV_G_ROUTING, &r); if (ret < 0) { diff --git a/src/core/CameraBuffer.cpp b/src/core/CameraBuffer.cpp index df093f09..ef446628 100644 --- a/src/core/CameraBuffer.cpp +++ b/src/core/CameraBuffer.cpp @@ -54,28 +54,17 @@ CameraBuffer::CameraBuffer(int cameraId, int usage, int memory, uint32_t size, i mU->flags = BUFFER_FLAG_INTERNAL; mU->sequence = -1; - switch (usage) { - case BUFFER_USAGE_PSYS_INPUT: - // follow through - case BUFFER_USAGE_PSYS_INTERNAL: - case BUFFER_USAGE_GENERAL: - if (PlatformData::isIsysEnabled(cameraId) && - PlatformData::isCSIFrontEndCapture(cameraId)) { - num_plane = CameraUtils::getNumOfPlanes(format); - } - break; - case BUFFER_USAGE_MIPI_CAPTURE: - case BUFFER_USAGE_METADATA: - num_plane = CameraUtils::getNumOfPlanes(format); - break; - default: - LOGE("Not supported Usage"); - break; - } - CLEAR(mMmapAddrs); CLEAR(mDmaFd); + if ((usage == BUFFER_USAGE_PSYS_INPUT || usage == BUFFER_USAGE_PSYS_INTERNAL || + usage == BUFFER_USAGE_GENERAL) && + (PlatformData::isIsysEnabled(cameraId) && PlatformData::isCSIFrontEndCapture(cameraId))) { + num_plane = CameraUtils::getNumOfPlanes(format); + } else if (usage == BUFFER_USAGE_MIPI_CAPTURE || usage == BUFFER_USAGE_METADATA) { + num_plane = CameraUtils::getNumOfPlanes(format); + } + initBuffer(memory, v4l2BufType, size, index, num_plane); } diff --git a/src/core/CameraDevice.cpp b/src/core/CameraDevice.cpp index aa25a52e..ebda1371 100644 --- a/src/core/CameraDevice.cpp +++ b/src/core/CameraDevice.cpp @@ -1127,6 +1127,7 @@ void CameraDevice::handleEvent(EventData eventData) { } break; } + case EVENT_ISYS_ERROR: { if (mCallback) { camera_msg_data_t data = {CAMERA_DEVICE_ERROR, {}}; diff --git a/src/core/DeviceBase.cpp b/src/core/DeviceBase.cpp index eab1b962..1e61fcd0 100644 --- a/src/core/DeviceBase.cpp +++ b/src/core/DeviceBase.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2023 Intel Corporation. + * Copyright (C) 2018-2024 Intel Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,8 @@ DeviceBase::DeviceBase(int cameraId, VideoNodeType nodeType, VideoNodeDirection mNeedSkipFrame(false), mDeviceCB(deviceCB), mMaxBufferNumber(MAX_BUFFER_COUNT), - mBufferQueuing(false) { + mBufferQueuing(false), + mBufType(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { LOG1("%s, device:%s", mCameraId, __func__, mName); mFrameSkipNum = PlatformData::getInitialSkipFrame(mCameraId); @@ -59,9 +60,6 @@ DeviceBase::DeviceBase(int cameraId, VideoNodeType nodeType, VideoNodeDirection nodeType); mDevice = new V4L2VideoNode(devName); -#ifdef LINUX_BUILD - mBufType = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -#endif } DeviceBase::~DeviceBase() { @@ -77,24 +75,23 @@ int DeviceBase::openDevice() { SyncManager::getInstance()->updateSyncCamNum(); // FRAME_SYNC_E -#ifdef LINUX_BUILD int ret = mDevice->Open(O_RDWR); if (ret) return ret; +#ifdef LINUX_BUILD int dev_caps = mDevice->GetDeviceCaps(); if (dev_caps & V4L2_CAP_VIDEO_CAPTURE) { mBufType = V4L2_BUF_TYPE_VIDEO_CAPTURE; } else { mBufType = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; } - +#else + mBufType = mDevice->GetBufferType(); +#endif PlatformData::setV4L2BufType(mCameraId, mBufType); return OK; -#else - return mDevice->Open(O_RDWR); -#endif } void DeviceBase::closeDevice() { @@ -159,10 +156,8 @@ int DeviceBase::queueBuffer(int64_t sequence) { mBufferQueuing = true; } -#ifdef LINUX_BUILD buffer->getV4L2Buffer().SetType(mBufType); -#endif int ret = onQueueBuffer(sequence, buffer); if (ret == OK) { ret = mDevice->PutFrame(&buffer->getV4L2Buffer()); @@ -348,11 +343,7 @@ int MainDevice::createBufferPool(const stream_t& config) { v4l2fmt.fmt.pix.sizeimage = 0; } -#ifdef LINUX_BUILD v4l2fmt.type = mBufType; -#else - v4l2fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -#endif V4L2Format tmpbuf{v4l2fmt}; int ret = mDevice->SetFormat(tmpbuf); CheckAndLogError(ret != OK, ret, "set v4l2 format failed ret=%d", ret); @@ -457,11 +448,7 @@ int DolCaptureDevice::createBufferPool(const stream_t& config) { v4l2fmt.fmt.pix.sizeimage = 0; v4l2fmt.fmt.pix_mp.field = 0; -#ifdef LINUX_BUILD v4l2fmt.type = mBufType; -#else - v4l2fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -#endif V4L2Format tmpbuf{v4l2fmt}; int ret = mDevice->SetFormat(tmpbuf); CheckAndLogError(ret != OK, ret, "set DOL v4l2 format failed ret=%d", ret); diff --git a/src/core/DeviceBase.h b/src/core/DeviceBase.h index 95d60ce6..549c6875 100644 --- a/src/core/DeviceBase.h +++ b/src/core/DeviceBase.h @@ -152,9 +152,7 @@ class DeviceBase : public EventSource { uint32_t mMaxBufferNumber; bool mBufferQueuing; -#ifdef LINUX_BUILD v4l2_buf_type mBufType; -#endif private: DISALLOW_COPY_AND_ASSIGN(DeviceBase); diff --git a/src/core/FileSource.cpp b/src/core/FileSource.cpp index 4b58d7b0..003faa3e 100644 --- a/src/core/FileSource.cpp +++ b/src/core/FileSource.cpp @@ -166,6 +166,10 @@ int FileSource::stop() { mProduceThread->requestExitAndWait(); mFrameFileBuffers.clear(); + while (mBufferQueue.size() > 0) { + mBufferQueue.pop(); + } + return OK; } diff --git a/src/core/RequestThread.cpp b/src/core/RequestThread.cpp index a2d13da9..0719195d 100644 --- a/src/core/RequestThread.cpp +++ b/src/core/RequestThread.cpp @@ -177,7 +177,7 @@ int RequestThread::processRequest(int bufferNum, camera_buffer_t** ubuffer, mActive = true; } - if (mRequestsInProcessing == 0) { + if (mRequestsInProcessing == 0 || !mPerframeControlSupport) { mRequestTriggerEvent |= NEW_REQUEST; mRequestSignal.signal(); } diff --git a/src/core/SofSource.cpp b/src/core/SofSource.cpp index 97faba1e..73518167 100644 --- a/src/core/SofSource.cpp +++ b/src/core/SofSource.cpp @@ -228,7 +228,8 @@ int SofSource::poll() { syncData.sequence = event.u.frame_sync.frame_sequence; syncData.timestamp.tv_sec = event.timestamp.tv_sec; syncData.timestamp.tv_usec = (event.timestamp.tv_nsec / 1000); - LOG2(" %s:sof event, event.id %u", syncData.sequence, __func__, event.id); + LOG2("camera:%d, %s, timestamp:%ld, sof event, event.id %u", mCameraId, + syncData.sequence, __func__, TIMEVAL2USECS(syncData.timestamp), event.id); TRACE_LOG_POINT("SofSource", "receive sof event", MAKE_COLOR(syncData.sequence), syncData.sequence); EventData eventData; diff --git a/src/core/psysprocessor/PGCommon.cpp b/src/core/psysprocessor/PGCommon.cpp index 0bb7df86..30a48e29 100644 --- a/src/core/psysprocessor/PGCommon.cpp +++ b/src/core/psysprocessor/PGCommon.cpp @@ -1097,6 +1097,13 @@ int PGCommon::prepareTerminalBuffers(const ia_binary_data* ipuParameters, buffer->isFlagsSet(BUFFER_FLAG_NO_FLUSH))) { flush = false; } +#ifdef LINUX_BUILD + // FILE_SOURCE_S + if (PlatformData::isFileSourceEnabled() && buffer->getMemory() == V4L2_MEMORY_USERPTR) { + flush = true; + } + // FILE_SOURCE_E +#endif ciprBuf = (buffer->getMemory() == V4L2_MEMORY_DMABUF) ? registerUserBuffer(buffer->getBufferSize(), buffer->getFd(), flush) : diff --git a/src/platformdata/CameraParser.cpp b/src/platformdata/CameraParser.cpp index 507a46f6..10225c78 100644 --- a/src/platformdata/CameraParser.cpp +++ b/src/platformdata/CameraParser.cpp @@ -690,6 +690,8 @@ void CameraParser::handleSensor(CameraParser* profiles, const char* name, const } } else if (strcmp(name, "isISYSCompression") == 0) { pCurrentCam->mISYSCompression = strcmp(atts[1], "true") == 0; + if (mStaticCfg->mMediaCfgId == IPU6_UPSTREAM_MEDIA_CFG) + pCurrentCam->mISYSCompression = false; } else if (strcmp(name, "isPSACompression") == 0) { pCurrentCam->mPSACompression = strcmp(atts[1], "true") == 0; } else if (strcmp(name, "isOFSCompression") == 0) { @@ -1431,7 +1433,14 @@ void CameraParser::parseRouteElement(CameraParser* profiles, const char* name, c idx += 2; } - mc.routes.push_back(route); + auto it = mc.routings.find(route.entityName); + if (it != mc.routings.end()) { + it->second.push_back(route); + } else { + std::vector routes; + routes.push_back(route); + mc.routings.insert(std::pair>(route.entityName, routes)); + } } void CameraParser::parseVideoElement(CameraParser* profiles, const char* name, diff --git a/src/v4l2/MediaControl.cpp b/src/v4l2/MediaControl.cpp index 54158cc3..03d6cb3d 100644 --- a/src/v4l2/MediaControl.cpp +++ b/src/v4l2/MediaControl.cpp @@ -810,6 +810,9 @@ int MediaControl::setFormat(int cameraId, const McFormat* format, int targetWidt tmt.format = mbusfmt; tmt.pad = link->sink->index; tmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + // VIRTUAL_CHANNEL_S + tmt.stream = format->stream; + // VIRTUAL_CHANNEL_E subDev->SetFormat(tmt); } } @@ -872,17 +875,25 @@ int MediaControl::mediaCtlSetup(int cameraId, MediaCtlConf* mc, int width, int h int ret = OK; // VIRTUAL_CHANNEL_S /* Set routing */ - for (auto& route : mc->routes) { - LOG1(" route entity:%s, sinkPad:%d, srcPad:%d, sinkStream:%d, srcStream:%d, flag:%d", - cameraId, route.entityName.c_str(), route.sinkPad, route.srcPad, route.sinkStream, - route.srcStream, route.flag); - + for (auto& routing : mc->routings) { + LOG1(" route entity:%s:", cameraId, routing.first.c_str()); + int num = routing.second.size(); + v4l2_subdev_route* routes = new v4l2_subdev_route[num]; + CheckAndLogError(!routes, NO_MEMORY, "Failed to alloc routes"); + for (int i = 0; i < num; i++) { + const McRoute& route = routing.second[i]; + v4l2_subdev_route r = {route.sinkPad, route.sinkStream, route.srcPad, route.srcStream, + route.flag}; + LOG1(" sinkPad:%d, srcPad:%d, sinkStream:%d, srcStream:%d, flag:%d", r.sink_pad, + r.source_pad, r.sink_stream, r.source_stream, route.flag); + + routes[i] = r; + } string subDeviceNodeName; - CameraUtils::getSubDeviceName(route.entityName.c_str(), subDeviceNodeName); + CameraUtils::getSubDeviceName(routing.first.c_str(), subDeviceNodeName); V4L2Subdevice* subDev = V4l2DeviceFactory::getSubDev(cameraId, subDeviceNodeName); - v4l2_subdev_route r = {route.sinkPad, route.sinkStream, route.srcPad, route.srcStream, - route.flag}; - ret = subDev->SetRouting(&r, 1); + ret = subDev->SetRouting(routes, num); + delete[] routes; CheckAndLogError(ret != 0, ret, "setRouting fail, ret:%d", ret); } // VIRTUAL_CHANNEL_E @@ -954,13 +965,25 @@ void MediaControl::mediaCtlClear(int cameraId, MediaCtlConf* mc) { // VIRTUAL_CHANNEL_S /* Clear routing */ - for (auto& route : mc->routes) { + for (auto& routing : mc->routings) { + LOG1(" route entity:%s:", cameraId, routing.first.c_str()); + int num = routing.second.size(); + v4l2_subdev_route* routes = new v4l2_subdev_route[num]; + CheckAndLogError(!routes, VOID_VALUE, "Failed to alloc routes"); + for (int i = 0; i < num; i++) { + const McRoute& route = routing.second[i]; + LOG1(" sinkPad:%d, srcPad:%d, sinkStream:%d, srcStream:%d, flag:%d", route.sinkPad, + route.srcPad, route.sinkStream, route.srcStream, route.flag); + v4l2_subdev_route r = {route.sinkPad, route.sinkStream, route.srcPad, route.srcStream, + route.flag & ~V4L2_SUBDEV_ROUTE_FL_ACTIVE}; + routes[i] = r; + } + string subDeviceNodeName; - CameraUtils::getSubDeviceName(route.entityName.c_str(), subDeviceNodeName); + CameraUtils::getSubDeviceName(routing.first.c_str(), subDeviceNodeName); V4L2Subdevice* subDev = V4l2DeviceFactory::getSubDev(cameraId, subDeviceNodeName); - v4l2_subdev_route r = {route.sinkPad, route.sinkStream, route.srcPad, route.srcStream, - route.flag & ~V4L2_SUBDEV_ROUTE_FL_ACTIVE}; - int ret = subDev->SetRouting(&r, 1); + int ret = subDev->SetRouting(routes, num); + delete[] routes; CheckAndLogError(ret != 0, VOID_VALUE, "Clear routing fail, ret:%d", ret); } // VIRTUAL_CHANNEL_E @@ -999,7 +1022,8 @@ bool MediaControl::checkHasSource(const MediaEntity* sink, const std::string& so // links[i] is the link to sink entity // pre is the link's source entity MediaEntity* pre = sink->links[i].source->entity; - if (pre->info.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR) { + if (pre->info.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR || + pre->info.type == MEDIA_ENT_T_V4L2_SUBDEV) { // if pre is sensor, return compare name result if (strncmp(source.c_str(), pre->info.name, source.length()) == 0) return true; } else { diff --git a/src/v4l2/MediaControl.h b/src/v4l2/MediaControl.h index 39174c5f..57c36ed2 100644 --- a/src/v4l2/MediaControl.h +++ b/src/v4l2/MediaControl.h @@ -174,7 +174,7 @@ struct McVideoNode { struct MediaCtlConf { std::vector ctls; std::vector links; - std::vector routes; + std::map> routings; std::vector formats; std::vector outputs; std::vector videoNodes;