Files
BPI-CM9-Linux/aml-comp/vendor/amlogic/mediactrlsrc/amlv4l2src/amlv4l2src.c
T

241 lines
6.6 KiB
C
Raw Normal View History

2026-08-13 11:28:40 +08:00
/*
* 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 <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <dlfcn.h>
#include <sys/ioctl.h>
#include <string.h>
#include <linux/videodev2.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <linux/media.h>
#include <sys/ioctl.h>
#include <linux/v4l2-subdev.h>
#include <errno.h>
#include <dirent.h>
#include <sys/sysmacros.h>
#include <sys/socket.h>
#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__);
}