729 lines
21 KiB
C++
729 lines
21 KiB
C++
/*
|
|
* Copyright (C) 2024 Amlogic Corporation.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "vsc_fuse.h"
|
|
#include "BinderClient.h"
|
|
#include <thread>
|
|
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
#include <fcntl.h>
|
|
#include <ctype.h>
|
|
#include <sys/prctl.h>
|
|
#include <android/log.h>
|
|
#include <cutils/android_reboot.h>
|
|
#include <cutils/properties.h>
|
|
#include <dirent.h>
|
|
|
|
#include "vsc_func.h"
|
|
|
|
int writeSys(const char *path, const char *val) {
|
|
int fd, size;
|
|
|
|
if ((fd = open(path, O_RDWR)) < 0) {
|
|
printf("writeSys, open %s fail.", path);
|
|
return -1;
|
|
}
|
|
|
|
size = strlen(val);
|
|
if (write(fd, val, size) != size) {
|
|
printf("writeSys, write %d size error: %s\n", size, strerror(errno));
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
|
|
int readSys(const char *path, char *buf, int count) {
|
|
int fd, len;
|
|
|
|
if ( NULL == buf ) {
|
|
printf("buf is NULL");
|
|
return -1;
|
|
}
|
|
|
|
if ((fd = open(path, O_RDONLY)) < 0) {
|
|
printf("readSys, open %s error(%s)", path, strerror (errno));
|
|
return -1;
|
|
}
|
|
|
|
len = read(fd, buf, count);
|
|
if (len < 0) {
|
|
printf("read %s error, %s\n", path, strerror(errno));
|
|
goto exit;
|
|
}
|
|
|
|
int i , j;
|
|
for (i = 0, j = 0; i <= len -1; i++) {
|
|
//change '\0' to 0x20(spacing), otherwise the string buffer will be cut off ,if the last char is '\0' should not replace it
|
|
if (0x0 == buf[i] && i < len - 1) {
|
|
buf[i] = 0x20;
|
|
}
|
|
/* delete all the character of '\n' */
|
|
if (0x0a != buf[i]) {
|
|
buf[j++] = buf[i];
|
|
}
|
|
}
|
|
buf[j] = 0x0;
|
|
|
|
//LOGI("read %s, result length:%d, val:%s\n", path, len, buf);
|
|
|
|
exit:
|
|
close(fd);
|
|
return len;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_frame_delay(fuse_req_t req, int value)
|
|
{
|
|
int valArray[3];
|
|
valArray[0] = value;
|
|
|
|
if (value < 0)
|
|
return -1;
|
|
|
|
writeSys("/sys/class/video_composer/vd_set_frame_delay", (const char*)valArray);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_frame_delay(fuse_req_t req, int *value)
|
|
{
|
|
int valArray[3];
|
|
int count = 0;
|
|
|
|
readSys("/sys/class/video_composer/vd_set_frame_delay", (char*)valArray, count);
|
|
*value = valArray[0];
|
|
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_limited_win_ratio(fuse_req_t req, const void *ptr)
|
|
{
|
|
/* We want to know the scaler performance for window setting.
|
|
(VSC GetLimitedWindow) If SOC can support any video size
|
|
(there isn't any limitation on in window setting), this function
|
|
Just returns 0x0. If SOC has some limitation, this function
|
|
returns the limited value. This function gets the Min/Max that
|
|
can be scaling setting.
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_limited_win_ratio(fuse_req_t req, struct v4l2_ext_vsc_scaler_ratio *ratio)
|
|
{
|
|
/* We want to know the scaler performance for window setting.
|
|
(VSC GetLimitedWindow) If SOC can support any video size
|
|
(there isn't any limitation on in window setting), this function
|
|
Just returns 0x0. If SOC has some limitation, this function
|
|
returns the limited value. This function gets the Min/Max that
|
|
can be scaling setting.
|
|
*/
|
|
ratio->h_scaleup_ratio = 0;
|
|
ratio->v_scaleup_ratio = 0;
|
|
ratio->h_scaledown_ratio = 0;
|
|
ratio->v_scaledown_ratio = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_occupation_sub_scaler(struct fuse_file_info *fi, int value)
|
|
{
|
|
/* After confirmation, this interface does not perform any operation */
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
if (!file || value < 0 || value > 2)
|
|
return -1;
|
|
file->data.occupation_sub_scaler = value;
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_occupation_sub_scaler(struct fuse_file_info *fi, int *value)
|
|
{
|
|
/* After confirmation, this interface does not perform any operation */
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file)
|
|
*value = file->data.occupation_sub_scaler;
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_pattern(fuse_req_t req, const void *ptr)
|
|
{
|
|
enum v4l2_ext_vsc_pattern *type = (enum v4l2_ext_vsc_pattern *)ptr;
|
|
|
|
if (*type == V4L2_EXT_VSC_PATTERN_SCALER) {
|
|
writeSys("/sys/class/video/video_test_pattern", "0 1 0xff0000");
|
|
writeSys("/sys/class/video/video_test_pattern", "0 1 0xff00");
|
|
writeSys("/sys/class/video/video_test_pattern", "0 1 0xff");
|
|
writeSys("/sys/class/video/video_test_pattern", "0 0 0xff");
|
|
} else if (*type == V4L2_EXT_VSC_PATTERN_DISPLAY) {
|
|
writeSys("/sys/class/video/postblend_test_pattern", "1 0xff0000");
|
|
writeSys("/sys/class/video/postblend_test_pattern", "1 0xff00");
|
|
writeSys("/sys/class/video/postblend_test_pattern", "1 0xff");
|
|
writeSys("/sys/class/video/postblend_test_pattern", "0 0xff");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_pattern(fuse_req_t req, enum v4l2_ext_vsc_pattern *type)
|
|
{
|
|
/* There is no need to implement the get function at present */
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_pixel_color_info(fuse_req_t req, const void *ptr)
|
|
{
|
|
/* Dump YUV data is required, and the pointer is obtained. This function will be improved later */
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_pixel_color_info(fuse_req_t req, struct v4l2_ext_vsc_pixel_color_info *info)
|
|
{
|
|
info->r.h = 2160;
|
|
info->r.w = 3840;
|
|
info->r.x = 0;
|
|
info->r.y = 0;
|
|
info->p_data = NULL;
|
|
info->compat_data = 0;
|
|
info->sizer = 0;
|
|
info->format = V4L2_EXT_VSC_COLOR_PIXEL_FORMAT_YUV;
|
|
info->depth = V4L2_EXT_VSC_COLOR_PIXEL_8BIT;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_rgb444(struct fuse_file_info *fi, int value)
|
|
{
|
|
/* After discussion, VPP postblond output only supports rgb444 */
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
if (!file || value > 1 || value < 0)
|
|
return -1;
|
|
file->data.rgb444 = value;
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_rgb444(struct fuse_file_info *fi, int *value)
|
|
{
|
|
/* After discussion, VPP postblond output only supports rgb444 */
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file)
|
|
*value = file->data.rgb444;
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_win_region(struct fuse_file_info *fi, const void *ptr)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
struct v4l2_ext_vsc_win_region *win = (struct v4l2_ext_vsc_win_region *)ptr;
|
|
int response = 0;
|
|
|
|
if (!file || win->rotation > V4L2_EXT_VSC_ROTATE_VFLIP)
|
|
return -1;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->setOriginalResolution(file->display_id, file->scaler_id, win);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_win_region(struct fuse_file_info *fi, struct v4l2_ext_vsc_win_region *win)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->getWinRegion(file->display_id, file->scaler_id, win);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_orbit_window(struct fuse_file_info *fi, const void *ptr)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
struct v4l2_ext_vsc_orbit_window *win = (struct v4l2_ext_vsc_orbit_window *)ptr;
|
|
|
|
if (file->binder.get())
|
|
return file->binder->setOrbitWindow(file->display_id, file->scaler_id, win);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_orbit_move(struct fuse_file_info *fi, const void *ptr)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
struct v4l2_ext_vsc_orbit_move *orbitMove = (struct v4l2_ext_vsc_orbit_move *)ptr;
|
|
|
|
if (file->binder.get())
|
|
return file->binder->setOrbitMove(file->display_id, file->scaler_id, orbitMove);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_zorder(struct fuse_file_info *fi, const void *ptr)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
struct v4l2_ext_vsc_zorder *z = (struct v4l2_ext_vsc_zorder *)ptr;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->setZorder(file->display_id, file->scaler_id, z);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_zorder(struct fuse_file_info *fi, struct v4l2_ext_vsc_zorder *z)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->getZorder(file->display_id, file->scaler_id, z);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_win_prop(struct fuse_file_info *fi, const void *ptr)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
struct v4l2_ext_vsc_win_prop *prop = (struct v4l2_ext_vsc_win_prop *)ptr;
|
|
int response = 0;
|
|
|
|
if (prop->win_mode > V4L2_EXT_VSC_WIN_MODE_PBP ||
|
|
prop->mirror_mode > V4L2_EXT_VSC_MIRROR_MODE_OFF ||
|
|
prop->mem_type > V4L2_EXT_VSC_MEMORY_TYPE_MULTI)
|
|
return -1;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->setWinProp(file->display_id, file->scaler_id, prop);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_win_prop(struct fuse_file_info *fi, struct v4l2_ext_vsc_win_prop *prop)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->getWinProp(file->display_id, file->scaler_id, prop);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_set_hdr_type(struct fuse_file_info *fi, int value)
|
|
{
|
|
if (value > V4L2_EXT_VSC_HDR_TYPE_HDR_RESERVED3 || value < 0)
|
|
return -1;
|
|
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
enum v4l2_ext_vsc_hdr_type hdr = (enum v4l2_ext_vsc_hdr_type)value;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->setHdrType(file->display_id, hdr);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_get_hdr_type(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->getHdrType(file->display_id, (enum v4l2_ext_vsc_hdr_type *)value);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_connect_info(struct fuse_file_info *fi, const void *ptr)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
struct v4l2_ext_vsc_connect_info *info = (struct v4l2_ext_vsc_connect_info *)ptr;
|
|
int response = 0;
|
|
|
|
if (info->in.src > V4L2_EXT_VSC_INPUT_SRC_DP ||
|
|
info->out > V4L2_EXT_VSC_DEST_AVE)
|
|
return -1;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->setConnectInfo(file->display_id, file->scaler_id, file->index, info);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_connect_info(struct fuse_file_info *fi, struct v4l2_ext_vsc_connect_info *info)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->getConnectInfo(file->display_id, file->scaler_id, info);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_freeze(struct fuse_file_info *fi, int value)
|
|
{
|
|
if (value != 0 && value != 1)
|
|
return -1;
|
|
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->setFreeze(file->display_id, file->scaler_id, value);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_freeze(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->getFreeze(file->display_id, file->scaler_id, value);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_freeze_frame_buffer(struct fuse_file_info *fi, int value)
|
|
{
|
|
if (value != 0 && value != 1)
|
|
return -1;
|
|
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->setFreezeFrameBuffer(file->display_id, file->scaler_id, value);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_freeze_frame_buffer(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->getFreezeFrameBuffer(file->display_id, file->scaler_id, value);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_adaptive_stream(struct fuse_file_info *fi, int value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
if (!file || value < 0 || value > 2)
|
|
return -1;
|
|
file->data.adaptive_stream = value;
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_adaptive_stream(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file)
|
|
*value = file->data.adaptive_stream;
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_vsc_aspectratio_policy(struct fuse_file_info *fi, const void *ptr)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
struct v4l2_ext_vsc_aspectratio_policy *policy =
|
|
(struct v4l2_ext_vsc_aspectratio_policy *)ptr;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->setAspectratio(file->display_id, file->scaler_id, policy);
|
|
|
|
file->data.policy = *policy;
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_get_vsc_aspectratio_policy(struct fuse_file_info *fi,
|
|
struct v4l2_ext_vsc_aspectratio_policy *policy)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file)
|
|
*policy = file->data.policy;
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_cid_set_bg_color(struct fuse_file_info *fi, int value)
|
|
{
|
|
if (value > V4L2_EXT_VSC_WIN_COLOR_GRAY || value < 0)
|
|
return -1;
|
|
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
enum v4l2_ext_vsc_win_color color = (enum v4l2_ext_vsc_win_color)value;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->setBgColor(file->display_id, file->scaler_id, color);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_cid_get_bg_color(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
int response = 0;
|
|
|
|
if (file->binder.get())
|
|
response = file->binder->getBgColor(file->display_id, (enum v4l2_ext_vsc_win_color *)value);
|
|
|
|
return response;
|
|
}
|
|
|
|
int v4l2_ext_set_hdmitx_timing_info(struct fuse_file_info *fi, const void *ptr)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
struct v4l2_ext_hdmitx_timing_info *info = (struct v4l2_ext_hdmitx_timing_info *)ptr;
|
|
|
|
if (file->binder.get())
|
|
return file->binder->setHdmitxTiming(file->display_id, info);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_hdmitx_timing_info(struct fuse_file_info *fi, struct v4l2_ext_hdmitx_timing_info *info)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file->binder.get())
|
|
return file->binder->getHdmitxTiming(file->display_id, info);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_cid_get_hdmitx_connection(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file->binder.get())
|
|
return file->binder->getHdmitxConnection(file->display_id, value);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_hdmitx_color_attr(struct fuse_file_info *fi, const void *ptr)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
struct v4l2_ext_hdmitx_color_attr *attr = (struct v4l2_ext_hdmitx_color_attr *)ptr;
|
|
|
|
if (file->binder.get())
|
|
return file->binder->setHdmitxColor(file->display_id, attr);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_hdmitx_color_attr(struct fuse_file_info *fi,
|
|
struct v4l2_ext_hdmitx_color_attr *attr)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file->binder.get())
|
|
return file->binder->getHdmitxColor(file->display_id, attr);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_cid_get_hdmitx_hdr_mode(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file->binder.get())
|
|
return file->binder->getHdmitxHdrType(file->display_id, value);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_cid_get_hdmitx_hdcp_version(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file->binder.get())
|
|
return file->binder->getHdmitxHdcpVersion(file->display_id, value);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_cid_set_hdmitx_hdr_policy(struct fuse_file_info *fi, int value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
if (file->binder.get())
|
|
return file->binder->setHdmitxHdrPolicy(file->display_id, value);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_cid_get_hdmitx_hdr_policy(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
if (file->binder.get())
|
|
return file->binder->getHdmitxHdrPolicy(file->display_id, value);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_cid_set_hdmitx_av_mute(struct fuse_file_info *fi, int value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
if (file->binder.get())
|
|
return file->binder->setHdmitxAvMute(file->display_id, value);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_cid_set_hdmitx_hdcp_auth(struct fuse_file_info *fi, int value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
if (file->binder.get())
|
|
return file->binder->setHdmitxHdcpAuth(file->display_id, value);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_cid_get_hdmitx_hdcp_status(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
if (file->binder.get())
|
|
return file->binder->getHdmitxHdcpStatus(file->display_id, value);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_cid_get_hdmitx_edid(struct fuse_file_info *fi, unsigned char *dat)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file->binder.get())
|
|
return file->binder->getHdmitxRawEdid(file->display_id, dat);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_device_capability(fuse_req_t req, struct v4l2_ext_vsc_device_capability *capability)
|
|
{
|
|
capability->num_planes = 2;
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_scan_mode(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
char val[80] = { 0 };
|
|
int mode = 0;
|
|
|
|
if (readSys("/sys/class/video_composer/di_vsc_scan_mode", val, sizeof(val)) >= 0) {
|
|
if (sscanf(val, "current di_vsc_scan_mode is %d.", &mode) == 1) {
|
|
*value = mode;
|
|
return 0;
|
|
}
|
|
}
|
|
if (file)
|
|
*value = file->data.scan_mode;
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_scan_mode(struct fuse_file_info *fi, int value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
char val[3] = { 0 };
|
|
if (!file || value > V4L2_EXT_VSC_SCAN_MODE_INTER_FIELD)
|
|
return -1;
|
|
file->data.scan_mode = value;
|
|
sprintf(val, "%d", value);
|
|
return writeSys("/sys/class/video_composer/di_vsc_scan_mode", val);
|
|
}
|
|
|
|
int v4l2_ext_get_pixed_to_pixed(struct fuse_file_info *fi, int *value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (file)
|
|
*value = file->data.pixel_to_pixel;
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_set_pixed_to_pixed(struct fuse_file_info *fi, int value)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
if (!file)
|
|
return -1;
|
|
file->data.pixel_to_pixel = value;
|
|
return 0;
|
|
}
|
|
|
|
void v4l2_ext_set_subscribe_state(
|
|
struct fuse_file_info *fi, int id, bool state)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (!file)
|
|
return;
|
|
|
|
for (int i = 0; i < file->subscribe_size; i++) {
|
|
if (id == file->subscribeInfo[i].event_id)
|
|
file->subscribeInfo[i].state = state;
|
|
}
|
|
}
|
|
|
|
bool v4l2_ext_get_subscribe_state(video_scaler_file_t *info, int id)
|
|
{
|
|
if (info->scaler_id >= VT_SCALER_MAX)
|
|
return false;
|
|
|
|
for (int i = 0; i < info->subscribe_size; i++) {
|
|
if (id == info->subscribeInfo[i].event_id) {
|
|
return info->subscribeInfo[i].state;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int v4l2_ext_set_event(video_scaler_file_t *info, struct v4l2_event *event)
|
|
{
|
|
if (!info)
|
|
return -1;
|
|
|
|
pthread_mutex_lock(&info->mutex);
|
|
if (info->pollHandle) {
|
|
if (v4l2_ext_get_subscribe_state(info, event->id)) {
|
|
memcpy(&info->receiveEvent, event, sizeof(struct v4l2_event));
|
|
info->poll_status = true;
|
|
fuse_lowlevel_notify_poll(info->pollHandle);
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&info->mutex);
|
|
return 0;
|
|
}
|
|
|
|
int v4l2_ext_get_event(struct fuse_file_info *fi, struct v4l2_event *event)
|
|
{
|
|
video_scaler_file_t *file = (video_scaler_file_t *)fi->fh;
|
|
|
|
if (!file)
|
|
return -1;
|
|
|
|
memcpy(event, &file->receiveEvent, sizeof(struct v4l2_event));
|
|
return 0;
|
|
}
|
|
|
|
VSC_EXT_FUNC_LIST
|