summaryrefslogtreecommitdiff
path: root/src/gstreamer
AgeCommit message (Expand)Author
2023-07-07meson: Fix space around colon issuesLaurent Pinchart
2023-07-04libcamera: Remove `StreamRoles` aliasBarnabás Pőcze
2023-06-28gstreamer: Drop libcamera_private dependencyUmang Jain
2023-06-18gstreamer: Add enable_auto_focus option to the GStreamer pluginCedric Nugteren
2023-01-05libcamera: Use C++17 [[fallthrough]] everywhereMatti Lehtimäki
2022-12-24gstreamer: Add bayer8 support to libcamerasrc elementPavel Machek
2022-11-25libcamera: stream: Turn StreamRole into scoped enumerationLaurent Pinchart
2022-11-21gstreamer: Do not lookup controls by idJacopo Mondi
2022-11-12gstreamer: Provide framerate support for libcamerasrcRishikesh Donadkar
2022-11-12gstreamer: Do not expose the caps before configuring the cameraRishikesh Donadkar
2022-09-12gstreamer: Check gstreamer version before using newer macrosVedant Paranjape
2022-09-01gstreamer: Provide colorimetry <> ColorSpace mappingsRishikesh Donadkar
2022-08-24gstreamer: Add support for additional RGB formatsLaurent Pinchart
2022-08-16libcamera: base: Make message.h and mutex.h privateLaurent Pinchart
2022-07-19gstreamer: Be pedantic on srcpads accessUmang Jain
2022-07-19libcamera: controls: Use std::optional to handle invalid control valuesChristian Rauch
2022-07-04gstreamer: Fix race conditions in task pause/resumeLaurent Pinchart
2022-07-04gstreamer: Split completed request processing to a separate functionLaurent Pinchart
2022-07-04gstreamer: Split request creation to a separate functionLaurent Pinchart
2022-07-04gstreamer: Fix pads lockingLaurent Pinchart
2022-07-04gstreamer: Use dedicated lock for request queuesLaurent Pinchart
2022-07-04gstreamer: Combine the two pad loops in the task run handlerLaurent Pinchart
2022-07-04gstreamer: Handle completed requests in the libcamerasrc taskLaurent Pinchart
2022-07-04gstreamer: Rename queued requests queue to queuedRequests_Laurent Pinchart
2022-07-04gstreamer: Move timestamp calculation out of pad loopLaurent Pinchart
2022-07-04gstreamer: Pass Stream to RequestWrap::addBuffer()Laurent Pinchart
2022-07-04gstreamer: Move variable to loop scopeLaurent Pinchart
2022-07-04gstreamer: Use gst_task_resume() when availableLaurent Pinchart
2022-03-29gstreamer: Fix typo in commentLaurent Pinchart
2022-01-19gstreamer: gstlibcamerasrc: Fix include orderingKieran Bingham
2021-12-04libcamera: base: shared_fd: Rename fd() to get()Laurent Pinchart
2021-11-24gstreamer: Convert to pragma onceKieran Bingham
2021-10-05gstreamer: Check if Stream configurations were generated correctlyJavier Martinez Canillas
2021-09-28gstreamer: Fix spelling of the work manager used in a util functionVedant Paranjape
2021-09-22gstreamer: Convert cm_singleton_ptr to static variableVedant Paranjape
2021-09-22gstreamer: Support planar formatsKieran Bingham
2021-08-30gstreamer: gstlibcameraallocator: Use offset in creating a bufferHirokazu Honda
2021-08-26gstreamer: Fix usage of default size for fixationNicolas Dufresne
2021-08-26libcamerasrc: Fix deadlock on EOSNicolas Dufresne
2021-08-26gstreamer: Fix concurrent access issues to CameraManagerNicolas Dufresne
2021-08-26gstreamer: Fix deadlock when last allocator ref is held by bufferNicolas Dufresne
2021-08-05gstreamer: Update format specifier in Request Pad templateVedant Paranjape
2021-07-28gstreamer: Store group_id in GstLibcameraSrcStateVedant Paranjape
2021-06-25libcamera: rename public libcamera dependencyKieran Bingham
2021-06-25gstreamer: Added virtual functions needed to support request padsVedant Paranjape
2021-06-07gstreamer: Add error checking in gst_libcamera_src_task_enter()Vedant Paranjape
2021-05-31gst: Fix compilation warning with GLib >= 2.62Laurent Pinchart
2021-03-28meson: Summarize which applications and adaptation layers are builtLaurent Pinchart
2021-03-23meson: Use subdir_done() to reduce indentationLaurent Pinchart
2021-03-15gst: Use the streams of CameraConfiguration when allocating buffersDafna Hirschfeld
"hl com"> * In all cases the data passed to the IPAInterface methods is serialized to * Plain Old Data, either for the purpose of passing it to the IPA context * plain C API, or to transmit the data to the isolated process through IPC. */ IPAManager::IPAManager() { unsigned int ipaCount = 0; /* User-specified paths take precedence. */ const char *modulePaths = utils::secure_getenv("LIBCAMERA_IPA_MODULE_PATH"); if (modulePaths) { for (const auto &dir : utils::split(modulePaths, ":")) { if (dir.empty()) continue; ipaCount += addDir(dir.c_str()); } if (!ipaCount) LOG(IPAManager, Warning) << "No IPA found in '" << modulePaths << "'"; } /* * When libcamera is used before it is installed, load IPAs from the * same build directory as the libcamera library itself. This requires * identifying the path of the libcamera.so, and referencing a relative * path for the IPA from that point. We need to recurse one level of * sub-directories to match the build tree. */ std::string root = utils::libcameraBuildPath(); if (!root.empty()) { std::string ipaBuildPath = root + "src/ipa"; constexpr int maxDepth = 1; LOG(IPAManager, Info) << "libcamera is not installed. Adding '" << ipaBuildPath << "' to the IPA search path"; ipaCount += addDir(ipaBuildPath.c_str(), maxDepth); } /* Finally try to load IPAs from the installed system path. */ ipaCount += addDir(IPA_MODULE_DIR); if (!ipaCount) LOG(IPAManager, Warning) << "No IPA found in '" IPA_MODULE_DIR "'"; } IPAManager::~IPAManager() { for (IPAModule *module : modules_) delete module; } /** * \brief Retrieve the IPA manager instance * * The IPAManager is a singleton and can't be constructed manually. This * function shall instead be used to retrieve the single global instance of the * manager. * * \return The IPA manager instance */ IPAManager *IPAManager::instance() { static IPAManager ipaManager; return &ipaManager; } /** * \brief Identify shared library objects within a directory * \param[in] libDir The directory to search for shared objects * \param[in] maxDepth The maximum depth of sub-directories to parse * \param[out] files A vector of paths to shared object library files * * Search a directory for .so files, allowing recursion down to sub-directories * no further than the depth specified by \a maxDepth. * * Discovered shared objects are added to the \a files vector. */ void IPAManager::parseDir(const char *libDir, unsigned int maxDepth, std::vector<std::string> &files) { struct dirent *ent; DIR *dir; dir = opendir(libDir); if (!dir) return; while ((ent = readdir(dir)) != nullptr) { if (ent->d_type == DT_DIR && maxDepth) { if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue; std::string subdir = std::string(libDir) + "/" + ent->d_name; /* Recursion is limited to maxDepth. */ parseDir(subdir.c_str(), maxDepth - 1, files); continue; } int offset = strlen(ent->d_name) - 3; if (offset < 0) continue; if (strcmp(&ent->d_name[offset], ".so")) continue; files.push_back(std::string(libDir) + "/" + ent->d_name); } closedir(dir); } /** * \brief Load IPA modules from a directory * \param[in] libDir The directory to search for IPA modules * \param[in] maxDepth The maximum depth of sub-directories to search * * This method tries to create an IPAModule instance for every shared object * found in \a libDir, and skips invalid IPA modules. * * Sub-directories are searched up to a depth of \a maxDepth. A \a maxDepth * value of 0 only searches the directory specified in \a libDir. * * \return Number of modules loaded by this call */ unsigned int IPAManager::addDir(const char *libDir, unsigned int maxDepth) { std::vector<std::string> files; parseDir(libDir, maxDepth, files); /* Ensure a stable ordering of modules. */ std::sort(files.begin(), files.end()); unsigned int count = 0; for (const std::string &file : files) { IPAModule *ipaModule = new IPAModule(file); if (!ipaModule->isValid()) { delete ipaModule; continue; } LOG(IPAManager, Debug) << "Loaded IPA module '" << file << "'"; modules_.push_back(ipaModule); count++; } return count; } /** * \brief Create an IPA proxy that matches a given pipeline handler * \param[in] pipe The pipeline handler that wants a matching IPA proxy * \param[in] minVersion Minimum acceptable version of IPA module * \param[in] maxVersion Maximum acceptable version of IPA module * * \return A newly created IPA proxy, or nullptr if no matching IPA module is * found or if the IPA proxy fails to initialize */ std::unique_ptr<IPAProxy> IPAManager::createIPA(PipelineHandler *pipe, uint32_t maxVersion, uint32_t minVersion) { IPAModule *m = nullptr; for (IPAModule *module : modules_) { if (module->match(pipe, minVersion, maxVersion)) { m = module; break; } } if (!m) return nullptr; /* * Load and run the IPA module in a thread if it has a valid signature, * or isolate it in a separate process otherwise. * * \todo Implement a better proxy selection */ const char *proxyName = isSignatureValid(m) ? "IPAProxyThread" : "IPAProxyLinux"; IPAProxyFactory *pf = nullptr; for (IPAProxyFactory *factory : IPAProxyFactory::factories()) { if (!strcmp(factory->name().c_str(), proxyName)) { pf = factory; break; } } if (!pf) { LOG(IPAManager, Error) << "Failed to get proxy factory"; return nullptr; } std::unique_ptr<IPAProxy> proxy = pf->create(m); if (!proxy->isValid()) { LOG(IPAManager, Error) << "Failed to load proxy"; return nullptr; } return proxy; } bool IPAManager::isSignatureValid(IPAModule *ipa) const { #if HAVE_IPA_PUBKEY File file{ ipa->path() }; if (!file.open(File::ReadOnly)) return false; Span<uint8_t> data = file.map(); if (data.empty()) return false; bool valid = pubKey_.verify(data, ipa->signature()); LOG(IPAManager, Debug) << "IPA module " << ipa->path() << " signature is " << (valid ? "valid" : "not valid"); return valid; #else return false; #endif } } /* namespace libcamera */