241 lines
6.6 KiB
C
241 lines
6.6 KiB
C
/*
|
||||
|
|
* 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__);
|
|||
|
|
}
|