Files
BPI-CM9-Linux/aml-comp/vendor/amlogic/mediactrlsrc/amlv4l2src/amlv4l2src.c
T
2026-08-24 10:03:24 +08:00

241 lines
6.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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__);
}