/* * Copyright (c) 2019 Amlogic, Inc. All rights reserved. * * This source code is subject to the terms and conditions defined in below * which is part of this source code package. * * Description: Amlv4l2src Library */ // Copyright (C) 2019 Amlogic, Inc. All rights reserved. // // All information contained herein is Amlogic confidential. // // This software is provided to you pursuant to Software License // Agreement (SLA) with Amlogic Inc ("Amlogic"). This software may be // used only in accordance with the terms of this agreement. // // Redistribution and use in source and binary forms, with or without // modification is strictly prohibited without prior written permission // from Amlogic. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "amlsrc.h" typedef void (*Func) (aml_src_t *); aml_src_t amlsrc = {0}; void for_vdinvideo_adapt_mipicam() { printf("enter for_vdinvideo_adapt_mipicam\n"); struct v4l2_subdev_format fmt; struct v4l2_mbus_framefmt mbus_format; memset(&mbus_format, 0, sizeof(mbus_format)); mbus_format.width = 1920; mbus_format.height = 1080; mbus_format.code = MEDIA_BUS_FMT_UYVY8_2X8; int videofd = open("/dev/v4l-subdev0", O_RDWR); if (videofd < 0) { printf("%s: open v4l-subdev0 failed\n", __func__); return; } memset(&fmt, 0, sizeof(fmt)); fmt.pad = 0; fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; fmt.format = mbus_format; int ret = ioctl(videofd, VIDIOC_SUBDEV_S_FMT, &fmt); if (ret < 0) { printf("%s: ioctl SUBDEV_S_FMT failed, ret %d\n", __func__, ret); close(videofd); return; } printf("exit for_vdinvideo_adapt_mipicam\n"); } void WriteSysfs(const char *path, const char *value) { int fd = open(path, O_WRONLY); if (fd < 0) { perror("open"); return; } if (write(fd, value, sizeof(value)) < 0) { perror("write"); } close(fd); } int aml_v4l2src_get_method(aml_src_t *pamlsrc, const char* devtype) { if (pamlsrc->initialize && pamlsrc->finalize && pamlsrc->start && pamlsrc->stop) { return 0; } char func_name[32]; sprintf(func_name, "aml_src_get_%s_method", devtype); void *handle = NULL; handle = dlopen("/usr/lib/libamlsrc.so", RTLD_LAZY); if (NULL == handle) { printf("dlopen libamlsrc.so error: %s\n", dlerror()); return -1; } printf("func_name: %s\n", func_name); Func func = (Func)dlsym(handle, func_name); if (!func) { printf("find function error\n"); dlclose(handle); handle = NULL; return -1; } func(pamlsrc); printf("initialize func addr: %p\n", pamlsrc->initialize); printf("finalize func addr: %p\n", pamlsrc->finalize); printf("start func addr: %p\n", pamlsrc->start); printf("stop func addr: %p\n", pamlsrc->stop); dlclose(handle); handle = NULL; return 0; } // static struct v4l2_capability *cap; int get_video_type(const char* devname, struct v4l2_capability* cap) { //get type by drive name int fd = open(devname, O_RDONLY); if (fd < 0) { printf("open001 \"%s\" error\n", devname); return -1; } /* 查询设备属性 */ // static struct v4l2_capability *cap; int ret = ioctl(fd, VIDIOC_QUERYCAP, cap); if (ret < 0) { printf("VIDIOC_QUERYCAP error\n"); close(fd); return -2; } printf("driver : %s\n", cap->driver); printf("device : %s\n", cap->card); printf("bus_info : %s\n", cap->bus_info); printf("version : %d\n", cap->version); close(fd); return 0; } int aml_v4l2src_connect(char** devname) { int ret = 0; struct v4l2_capability cap; printf("[API:%s:%d]Enter, devname : %s\n", __func__, __LINE__, *devname); ret = get_video_type(*devname, &cap); if (0 != ret) { printf("Error: get video type failed: %s\n", *devname); return -1; } printf("strcmp cap.driver: %s\n", cap.driver); // usb cam: if (0 == strcmp("uvcvideo",(char*)(cap.driver))) { printf("[API:%s:%d]Exit, USB camera\n", __func__, __LINE__); // *dev_type = 0; return 0; //as usb } // hdmi rx and s6 mipi cam: if (0 == strcmp("vdinvideo",(char*)(cap.driver)) || 0 == strcmp("vdin_video",(char*)(cap.driver))) { //s6 video 70:vdin_video,we use it adapt mipicam if (0 == strcmp("meson-s6",(char*)(cap.card))) { for_vdinvideo_adapt_mipicam(); return 3; }else if (0 == aml_v4l2src_get_method(&amlsrc, "hdmi")) { // *dev_type = 3; if (amlsrc.initialize) amlsrc.initialize(*devname); else printf("Amlsrc no init interf\n"); printf("[API:%s:%d]Exit, HDMI RX\n", __func__, __LINE__); // aml_v4l2src_streamon(); return 3; } } // hdmi tx: if (0 == strcmp("amlvideo2",(char*)(cap.driver))) { printf("[API:%s:%d]Exit, HDMI TX\n", __func__, __LINE__); // *dev_type = 4; return 4; } printf("[API:%s:%d]Exit, do nothing (devname : %s)\n", __func__, __LINE__, *devname); // *dev_type = -1; return -1; } void aml_v4l2src_disconnect() { printf("[API:%s:%d]Enter\n", __func__, __LINE__); if (amlsrc.finalize) amlsrc.finalize(); if (amlsrc.handle) { dlclose(amlsrc.handle); amlsrc.handle = NULL; } printf("[API:%s:%d:%p]Exit\n", __func__, __LINE__,amlsrc.handle); } void aml_v4l2src_streamon() { printf("[API:%s:%d]Enter\n", __func__, __LINE__); if (amlsrc.start) amlsrc.start(); printf("[API:%s:%d]Exit\n", __func__, __LINE__); } void aml_v4l2src_streamoff() { printf("[API:%s:%d]Enter\n", __func__, __LINE__); if (amlsrc.stop) amlsrc.stop(); printf("[API:%s:%d]Exit\n", __func__, __LINE__); }