/**************************************************************************** * apps/system/nxcodec/nxcodec.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you 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. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include "nxcodec.h" /**************************************************************************** * Private Functions ****************************************************************************/ static inline bool nxcodec_splane_video(FAR struct v4l2_capability *cap) { return (cap->capabilities & V4L2_CAP_VIDEO_M2M) || ((cap->capabilities & V4L2_CAP_STREAMING) && (cap->capabilities & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_CAPTURE))); } static inline bool nxcodec_mplane_video(FAR struct v4l2_capability *cap) { return (cap->capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) || ((cap->capabilities & V4L2_CAP_STREAMING) && (cap->capabilities & (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_CAPTURE_MPLANE))); } static int nxcodec_prepare_contexts(FAR nxcodec_t *codec) { struct v4l2_capability cap; int ret; memset(&cap, 0, sizeof(cap)); ret = ioctl(codec->fd, VIDIOC_QUERYCAP, &cap); if (ret < 0) { return -errno; } if (nxcodec_mplane_video(&cap)) { codec->capture.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; codec->output.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; return 0; } if (nxcodec_splane_video(&cap)) { codec->capture.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; codec->output.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; return 0; } return -EINVAL; } /**************************************************************************** * Public Functions ****************************************************************************/ int nxcodec_init(FAR nxcodec_t *codec) { int ret; codec->fd = open(codec->devname, O_RDWR | O_NONBLOCK); if (codec->fd < 0) { return -errno; } ret = nxcodec_prepare_contexts(codec); if (ret < 0) { goto err0; } ret = nxcodec_context_get_format(&codec->output); if (ret < 0) { printf("v4l2 output format not supported\n"); goto err0; } ret = nxcodec_context_get_format(&codec->capture); if (ret < 0) { printf("v4l2 capture format not supported\n"); goto err0; } codec->output.format.type = codec->output.type; ret = nxcodec_context_set_format(&codec->output); if (ret < 0) { printf("can't set v4l2 output format\n"); goto err0; } codec->output.fd = open(codec->output.filename, O_RDONLY); if (codec->output.fd < 0) { printf("Failed to open output file %s \n", codec->output.filename); ret = -errno; goto err0; } codec->capture.format.type = codec->capture.type; ret = nxcodec_context_set_format(&codec->capture); if (ret < 0) { printf("can't to set v4l2 capture format\n"); goto err1; } codec->capture.fd = open(codec->capture.filename, O_WRONLY | O_CREAT, 0644); if (codec->capture.fd < 0) { printf("Failed to open input file %s \n", codec->capture.filename); ret = -errno; goto err1; } return 0; err1: close(codec->output.fd); err0: close(codec->fd); return ret; } int nxcodec_start(FAR nxcodec_t *codec) { int ret; ret = nxcodec_context_init(&codec->output); if (ret < 0) { printf("can't request output buffers\n"); return ret; } ret = nxcodec_context_set_status(&codec->output, VIDIOC_STREAMON); if (ret < 0) { printf("set output VIDIOC_STREAMON failed\n"); goto err0; } ret = nxcodec_context_init(&codec->capture); if (ret < 0) { printf("can't request capture buffers\n"); goto err0; } ret = nxcodec_context_set_status(&codec->capture, VIDIOC_STREAMON); if (ret < 0) { printf("set capture VIDIOC_STREAMON failed\n"); goto err1; } ret = nxcodec_context_enqueue_frame(&codec->output); if (ret < 0 && ret != -EAGAIN) { goto err1; } return 0; err1: nxcodec_context_uninit(&codec->capture); err0: nxcodec_context_uninit(&codec->output); return ret; } int nxcodec_stop(FAR nxcodec_t *codec) { int ret; if (!codec) { return 0; } nxcodec_context_uninit(&codec->output); ret = nxcodec_context_set_status(&codec->output, VIDIOC_STREAMOFF); if (ret < 0) { printf("set output VIDIOC_STREAMOFF failed\n"); return ret; } nxcodec_context_uninit(&codec->capture); ret = nxcodec_context_set_status(&codec->capture, VIDIOC_STREAMOFF); if (ret < 0) { printf("set capture VIDIOC_STREAMOFF failed\n"); return ret; } return 0; } int nxcodec_uninit(FAR nxcodec_t *codec) { close(codec->capture.fd); close(codec->output.fd); close(codec->fd); return 0; }