| /* Copyright 2023 The ChromiumOS Authors | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| // NOLINTNEXTLINE(build/include) | |
| #include "tools/mctk/mcdev.h" | |
| #include <re2/re2.h> | |
| #include <unistd.h> | |
| #include <optional> | |
| #include <string> | |
| #include <vector> | |
| #include "tools/mctk/debug.h" | |
| #include "tools/mctk/yaml_tree.h" | |
| /* | |
| * PUBLIC | |
| */ | |
| V4lMcDev::~V4lMcDev() { | |
| if (fd_) | |
| close(*fd_); | |
| } | |
| bool V4lMcDev::ResetLinks() { | |
| bool ok = true; | |
| for (auto link : all_links_) { | |
| if (!link->IsDataLink() || link->IsImmutable()) | |
| continue; | |
| ok = ok && link->SetEnable(false); | |
| } | |
| return ok; | |
| } | |
| V4lMcEntity* V4lMcDev::EntityById(__u32 id) { | |
| for (auto& entity : entities_) { | |
| if (entity->desc_.id == id) | |
| return entity.get(); | |
| } | |
| return nullptr; | |
| } | |
| V4lMcEntity* V4lMcDev::EntityByName(std::string name) { | |
| for (auto& entity : entities_) { | |
| if (std::string(entity->desc_.name) == name) | |
| return entity.get(); | |
| } | |
| return nullptr; | |
| } | |
| V4lMcEntity* V4lMcDev::EntityByNameRegex(std::string regex) { | |
| RE2 re(regex); | |
| if (!re.ok()) | |
| MCTK_PANIC("Invalid regex: " + regex); | |
| for (auto& entity : entities_) { | |
| if (RE2::FullMatch(entity->desc_.name, re)) | |
| return entity.get(); | |
| } | |
| return nullptr; | |
| } | |
| /* | |
| * PRIVATE | |
| */ | |
| void V4lMcDev::BuildCrosslinks() { | |
| /* Build MC-wide lists of pads and links */ | |
| for (auto& entity : entities_) { | |
| for (auto& pad : entity->pads_) | |
| all_pads_.push_back(pad.get()); | |
| for (auto& link : entity->links_) | |
| all_links_.push_back(link.get()); | |
| } | |
| /* Let links/pads point at each other */ | |
| for (auto* link : all_links_) { | |
| for (auto* pad : all_pads_) { | |
| /* Comparing two struct media_pad_desc */ | |
| if (!memcmp(&pad->desc_, &link->desc_.source, sizeof(pad->desc_))) { | |
| link->src_ = pad; | |
| pad->links_.push_back(link); | |
| } | |
| /* Comparing two struct media_pad_desc */ | |
| if (!memcmp(&pad->desc_, &link->desc_.sink, sizeof(pad->desc_))) { | |
| link->sink_ = pad; | |
| /* Not doing: pad->links_.push_back(link); | |
| * since we only store outgoing links in entity's/pad's array | |
| */ | |
| } | |
| } | |
| } | |
| } |