/* * Copyright (C) 2014-2017 Intel Corporation * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "MediaEntity" #include #include #include "MediaEntity.h" #include "LogHelper.h" NAMESPACE_DECLARATION { MediaEntity::MediaEntity(struct media_entity_desc &entity, struct media_link_desc *links, struct media_pad_desc *pads) : mInfo(entity), mDevice(nullptr) { LOGI("@%s: %s, id: %d", __FUNCTION__, entity.name, entity.id); mLinks.reserve(entity.links); mPads.reserve(entity.pads); mLinks.clear(); mPads.clear(); if (links != nullptr) { for (int i = 0; i < entity.links; i++) { LOGI("link %d: src entity %d: %d --> sink entity %d:%d (%s%s%s)", i, links[i].source.entity, links[i].source.index, links[i].sink.entity, links[i].sink.index, (links[i].flags & MEDIA_LNK_FL_ENABLED)?"enabled":"disabled", (links[i].flags & MEDIA_LNK_FL_IMMUTABLE)?" immutable":"", (links[i].flags & MEDIA_LNK_FL_DYNAMIC)?" dynamic":""); mLinks.push_back(links[i]); } } if (pads != nullptr) { for (int i = 0; i < entity.pads; i++) { LOGI("pad %d (%s)", pads[i].index, (pads[i].flags & MEDIA_PAD_FL_SINK)?"SINK":"SOURCE"); mPads.push_back(pads[i]); } } } MediaEntity::~MediaEntity() { LOGI("@%s", __FUNCTION__); CLEAR(mInfo); mLinks.clear(); mPads.clear(); if (mDevice != nullptr) { if (mDevice->isOpen()) mDevice->close(); mDevice.reset(); mDevice = nullptr; } } status_t MediaEntity::getDevice(std::shared_ptr &device) { LOGI("@%s", __FUNCTION__); status_t status = NO_ERROR; if (mDevice == nullptr || !mDevice->isOpen()) { LOGI("Opening device"); status = openDevice(mDevice); } if (status == NO_ERROR) device = mDevice; else device = nullptr; return status; } status_t MediaEntity::openDevice(std::shared_ptr &device) { LOGI("@%s", __FUNCTION__); status_t status = UNKNOWN_ERROR; int ret = 0; char sysname[1024]; int major = mInfo.v4l.major; int minor = mInfo.v4l.minor; std::ostringstream stringStream; stringStream << "/sys/dev/char/" << major << ":" << minor; std::string devNameStr = stringStream.str(); ret = readlink(devNameStr.c_str(), sysname, sizeof(sysname)); if (ret < 0) { LOGE("Unable to find device node"); } else { sysname[ret] = 0; char *lastSlash = strrchr(sysname, '/'); if (lastSlash == nullptr) { LOGE("Invalid sysfs device path"); return status; } stringStream.str(""); stringStream << "/dev/" << lastSlash + 1; devNameStr = stringStream.str(); const char *devname = devNameStr.c_str(); LOGI("Device node : %s", devname); device.reset(); if (mInfo.type == MEDIA_ENT_T_DEVNODE_V4L) { device = std::make_shared(devname); } else { device = std::make_shared(devname); } status = device->open(); if (status != NO_ERROR) { LOGE("Failed to open device %s", devname); device.reset(); } } return status; } void MediaEntity::updateLinks(const struct media_link_desc *links) { LOGI("@%s", __FUNCTION__); mLinks.clear(); LOGI("entity name: %s, id: %d, pads: %d, links: %d", mInfo.name, mInfo.id, mInfo.pads, mInfo.links); for (int i = 0; i < mInfo.links; i++) { LOGI("link %d: pad %d --> sink entity %d:%d (%s%s%s)", i, links[i].source.index, links[i].sink.entity, links[i].sink.index, (links[i].flags & MEDIA_LNK_FL_ENABLED)?"enabled":"disabled", (links[i].flags & MEDIA_LNK_FL_IMMUTABLE)?" immutable":"", (links[i].flags & MEDIA_LNK_FL_DYNAMIC)?" dynamic":""); mLinks.push_back(links[i]); } } V4L2DeviceType MediaEntity::getType() { LOGI("@%s", __FUNCTION__); switch (mInfo.type) { case MEDIA_ENT_T_DEVNODE_V4L: return DEVICE_VIDEO; break; case MEDIA_ENT_T_V4L2_SUBDEV: return SUBDEV_GENERIC; break; case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR: return SUBDEV_SENSOR; break; case MEDIA_ENT_T_V4L2_SUBDEV_FLASH: return SUBDEV_FLASH; break; case MEDIA_ENT_T_V4L2_SUBDEV_LENS: return SUBDEV_LENS; break; default: LOGE("Unknown media entity type: %d", mInfo.type); return UNKNOWN_TYPE; } } } NAMESPACE_DECLARATION_END