add m2m decoder/encoder test
Signed-off-by: yangsen5 <yangsen5@xiaomi.com>
This commit is contained in:
parent
6b9d51793f
commit
9312a74004
30
system/nxcodec/Kconfig
Normal file
30
system/nxcodec/Kconfig
Normal file
@ -0,0 +1,30 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
config SYSTEM_NXCODEC
|
||||
bool "NxCodec test application"
|
||||
default n
|
||||
---help---
|
||||
Enable support for the NxCodec test application and optional
|
||||
command line interface.
|
||||
|
||||
if SYSTEM_NXCODEC
|
||||
|
||||
config SYSTEM_NXCODEC_PROGNAME
|
||||
string "Program name"
|
||||
default "nxcodec"
|
||||
---help---
|
||||
This is the name of the program that will be used when the NSH ELF
|
||||
program is installed.
|
||||
|
||||
config SYSTEM_NXCODEC_PRIORITY
|
||||
int "nxcodec task priority"
|
||||
default 100
|
||||
|
||||
config SYSTEM_NXCODEC_STACKSIZE
|
||||
int "nxcodec stack size"
|
||||
default DEFAULT_TASK_STACKSIZE
|
||||
|
||||
endif # SYSTEM_NXCODEC
|
23
system/nxcodec/Make.defs
Normal file
23
system/nxcodec/Make.defs
Normal file
@ -0,0 +1,23 @@
|
||||
############################################################################
|
||||
# apps/system/nxcodec/Make.defs
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifneq ($(CONFIG_SYSTEM_NXCODEC),)
|
||||
CONFIGURED_APPS += $(APPDIR)/system/nxcodec
|
||||
endif
|
36
system/nxcodec/Makefile
Normal file
36
system/nxcodec/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
############################################################################
|
||||
# apps/system/nxcodec/Makefile
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
CSRCS = nxcodec.c nxcodec_context.c
|
||||
|
||||
# nxcodec test built-in application info
|
||||
|
||||
PROGNAME = $(CONFIG_SYSTEM_NXCODEC_PROGNAME)
|
||||
PRIORITY = $(CONFIG_SYSTEM_NXCODEC_PRIORITY)
|
||||
STACKSIZE = $(CONFIG_SYSTEM_NXCODEC_STACKSIZE)
|
||||
MODULE = $(CONFIG_SYSTEM_NXCODEC)
|
||||
|
||||
# nxcodec test
|
||||
|
||||
MAINSRC = nxcodec_main.c
|
||||
|
||||
include $(APPDIR)/Application.mk
|
259
system/nxcodec/nxcodec.c
Normal file
259
system/nxcodec/nxcodec.c
Normal file
@ -0,0 +1,259 @@
|
||||
/****************************************************************************
|
||||
* 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 <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
if (codec->output.fdesc.pixelformat !=
|
||||
codec->output.format.fmt.pix.pixelformat)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
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 input file %s \n", codec->output.filename);
|
||||
ret = -errno;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (codec->capture.fdesc.pixelformat !=
|
||||
codec->capture.format.fmt.pix.pixelformat)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
51
system/nxcodec/nxcodec.h
Normal file
51
system/nxcodec/nxcodec.h
Normal file
@ -0,0 +1,51 @@
|
||||
/****************************************************************************
|
||||
* apps/system/nxcodec/nxcodec.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __APPS_SYSTEM_NXCODEC_NXCODEC_H
|
||||
#define __APPS_SYSTEM_NXCODEC_NXCODEC_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "nxcodec_context.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct nxcodec_s
|
||||
{
|
||||
char devname[PATH_MAX];
|
||||
int fd;
|
||||
nxcodec_context_t capture;
|
||||
nxcodec_context_t output;
|
||||
} nxcodec_t;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
int nxcodec_init(FAR nxcodec_t *codec);
|
||||
int nxcodec_start(FAR nxcodec_t *codec);
|
||||
int nxcodec_stop(FAR nxcodec_t *codec);
|
||||
int nxcodec_uninit(FAR nxcodec_t *codec);
|
||||
|
||||
#endif /* __APPS_SYSTEM_NXCODEC_NXCODEC_H */
|
383
system/nxcodec/nxcodec_context.c
Normal file
383
system/nxcodec/nxcodec_context.c
Normal file
@ -0,0 +1,383 @@
|
||||
/****************************************************************************
|
||||
* apps/system/nxcodec/nxcodec_context.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 <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/nuttx.h>
|
||||
|
||||
#include "nxcodec_context.h"
|
||||
#include "nxcodec.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define NXCODEC_CONTEXT_BUFNUMBER 3
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static inline FAR nxcodec_t *
|
||||
nxcodec_context_to_nxcodec(FAR nxcodec_context_t *ctx)
|
||||
{
|
||||
return V4L2_TYPE_IS_OUTPUT(ctx->type) ?
|
||||
container_of(ctx, nxcodec_t, output) :
|
||||
container_of(ctx, nxcodec_t, capture);
|
||||
}
|
||||
|
||||
static FAR nxcodec_context_buf_t *
|
||||
nxcodec_context_dequeue_buf(FAR nxcodec_context_t *ctx)
|
||||
{
|
||||
FAR nxcodec_t *codec = nxcodec_context_to_nxcodec(ctx);
|
||||
struct v4l2_buffer buf;
|
||||
int ret;
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.type = ctx->type;
|
||||
|
||||
ret = ioctl(codec->fd, VIDIOC_DQBUF, &buf);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("type: %d VIDIOC_DQBUF, err: %s\n", ctx->type, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->buf[buf.index].free = true;
|
||||
ctx->buf[buf.index].buf = buf;
|
||||
|
||||
return &ctx->buf[buf.index];
|
||||
}
|
||||
|
||||
static FAR nxcodec_context_buf_t *
|
||||
nxcodec_context_get_freebuf(FAR nxcodec_context_t *ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (V4L2_TYPE_IS_OUTPUT(ctx->type))
|
||||
{
|
||||
while (nxcodec_context_dequeue_buf(ctx));
|
||||
}
|
||||
|
||||
for (i = 0; i < ctx->nbuffers; i++)
|
||||
{
|
||||
if (ctx->buf[i].free)
|
||||
{
|
||||
return &ctx->buf[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int nxcodec_context_write_data(FAR nxcodec_context_t *ctx,
|
||||
FAR const char *buf, int size)
|
||||
{
|
||||
return write(ctx->fd, buf, size) < 0 ? -errno : 0;
|
||||
}
|
||||
|
||||
static int nxcodec_context_read_yuv_data(FAR nxcodec_context_t *ctx,
|
||||
FAR char *buf,
|
||||
FAR uint32_t *bytesused)
|
||||
{
|
||||
size_t buflen = ctx->format.fmt.pix.width *
|
||||
ctx->format.fmt.pix.height * 3 / 2;
|
||||
ssize_t ret;
|
||||
|
||||
ret = read(ctx->fd, buf, buflen);
|
||||
if (ret <= 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
*bytesused = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nxcodec_context_read_h264_data(FAR nxcodec_context_t *ctx,
|
||||
FAR char *buf,
|
||||
FAR uint32_t *bytesused)
|
||||
{
|
||||
char start_code[4];
|
||||
ssize_t ret;
|
||||
int size;
|
||||
|
||||
memset(start_code, 0, 4);
|
||||
|
||||
ret = read(ctx->fd, buf, 4);
|
||||
if (ret <= 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (buf[0] == 0x00 && buf[1] == 0x00 &&
|
||||
buf[2] == 0x00 && buf[3] == 0x01)
|
||||
{
|
||||
size = 4;
|
||||
while (1)
|
||||
{
|
||||
ret = read(ctx->fd, buf + size, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
start_code[0] = start_code[1];
|
||||
start_code[1] = start_code[2];
|
||||
start_code[2] = start_code[3];
|
||||
start_code[3] = *(buf + size);
|
||||
size++;
|
||||
|
||||
if (start_code[0] == 0x00 && start_code[1] == 0x00 &&
|
||||
start_code[2] == 0x00 && start_code[3] == 0x01)
|
||||
{
|
||||
size -= 4;
|
||||
lseek(ctx->fd, -4, SEEK_CUR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*bytesused = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int nxcodec_context_set_status(FAR nxcodec_context_t *ctx, uint32_t cmd)
|
||||
{
|
||||
FAR nxcodec_t *codec = nxcodec_context_to_nxcodec(ctx);
|
||||
|
||||
return ioctl(codec->fd, cmd, &ctx->type) < 0 ? -errno : 0;
|
||||
}
|
||||
|
||||
int nxcodec_context_enqueue_frame(FAR nxcodec_context_t *ctx)
|
||||
{
|
||||
FAR nxcodec_t *codec = nxcodec_context_to_nxcodec(ctx);
|
||||
FAR nxcodec_context_buf_t *buf;
|
||||
int ret;
|
||||
|
||||
buf = nxcodec_context_get_freebuf(ctx);
|
||||
if (!buf)
|
||||
{
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (ctx->format.fmt.pix.pixelformat == V4L2_PIX_FMT_H264)
|
||||
{
|
||||
ret = nxcodec_context_read_h264_data(ctx,
|
||||
buf->addr,
|
||||
&buf->buf.bytesused);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else if (ctx->format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
|
||||
{
|
||||
ret = nxcodec_context_read_yuv_data(ctx,
|
||||
buf->addr,
|
||||
&buf->buf.bytesused);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ioctl(codec->fd, VIDIOC_QBUF, &buf->buf);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
buf->free = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nxcodec_context_dequeue_frame(FAR nxcodec_context_t *ctx)
|
||||
{
|
||||
FAR nxcodec_t *codec = nxcodec_context_to_nxcodec(ctx);
|
||||
FAR nxcodec_context_buf_t *buf;
|
||||
int ret;
|
||||
|
||||
buf = nxcodec_context_dequeue_buf(ctx);
|
||||
if (!buf)
|
||||
{
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (buf->buf.length > 0)
|
||||
{
|
||||
nxcodec_context_write_data(ctx, buf->addr, buf->buf.bytesused);
|
||||
}
|
||||
|
||||
ret = ioctl(codec->fd, VIDIOC_QBUF, &buf->buf);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
buf->free = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nxcodec_context_get_format(FAR nxcodec_context_t *ctx)
|
||||
{
|
||||
FAR nxcodec_t *codec = nxcodec_context_to_nxcodec(ctx);
|
||||
|
||||
memset(&ctx->fdesc, 0, sizeof(ctx->fdesc));
|
||||
ctx->fdesc.type = ctx->type;
|
||||
|
||||
return ioctl(codec->fd, VIDIOC_ENUM_FMT, &ctx->fdesc) < 0 ? -errno : 0;
|
||||
}
|
||||
|
||||
int nxcodec_context_set_format(FAR nxcodec_context_t *ctx)
|
||||
{
|
||||
FAR nxcodec_t *codec = nxcodec_context_to_nxcodec(ctx);
|
||||
|
||||
return ioctl(codec->fd, VIDIOC_S_FMT, &ctx->format) < 0 ? -errno : 0;
|
||||
}
|
||||
|
||||
int nxcodec_context_init(FAR nxcodec_context_t *ctx)
|
||||
{
|
||||
FAR nxcodec_t *codec = nxcodec_context_to_nxcodec(ctx);
|
||||
struct v4l2_requestbuffers req;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.count = NXCODEC_CONTEXT_BUFNUMBER;
|
||||
req.memory = V4L2_MEMORY_MMAP;
|
||||
req.type = ctx->type;
|
||||
|
||||
ret = ioctl(codec->fd, VIDIOC_REQBUFS, &req);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("type: %d VIDIOC_REQBUFS failed: %s\n",
|
||||
ctx->type, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ctx->nbuffers = req.count;
|
||||
ctx->buf = calloc(ctx->nbuffers, sizeof(nxcodec_context_buf_t));
|
||||
if (!ctx->buf)
|
||||
{
|
||||
printf("type: %d malloc enomem\n", ctx->type);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < ctx->nbuffers; i++)
|
||||
{
|
||||
FAR nxcodec_context_buf_t *buf = &ctx->buf[i];
|
||||
|
||||
buf->buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf->buf.type = ctx->type;
|
||||
buf->buf.index = i;
|
||||
|
||||
ret = ioctl(codec->fd, VIDIOC_QUERYBUF, &buf->buf);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
buf->length = buf->buf.length;
|
||||
buf->addr = mmap(NULL,
|
||||
buf->buf.length,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
codec->fd,
|
||||
buf->buf.m.offset);
|
||||
|
||||
if (buf->addr == MAP_FAILED)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
buf->free = true;
|
||||
|
||||
if (V4L2_TYPE_IS_OUTPUT(ctx->type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = ioctl(codec->fd, VIDIOC_QBUF, &buf->buf);
|
||||
if (ret < 0)
|
||||
{
|
||||
munmap(buf->addr, buf->length);
|
||||
goto error;
|
||||
}
|
||||
|
||||
buf->free = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(ctx->buf);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
void nxcodec_context_uninit(FAR nxcodec_context_t *ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!ctx->buf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ctx->nbuffers; i++)
|
||||
{
|
||||
FAR nxcodec_context_buf_t *buf = &ctx->buf[i];
|
||||
|
||||
if (buf->addr && buf->length)
|
||||
{
|
||||
if (munmap(buf->addr, buf->length) < 0)
|
||||
{
|
||||
printf("type: %d unmap plane (%s))\n",
|
||||
ctx->type, strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(ctx->buf);
|
||||
}
|
65
system/nxcodec/nxcodec_context.h
Normal file
65
system/nxcodec/nxcodec_context.h
Normal file
@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
* apps/system/nxcodec/nxcodec_context.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __APP_SYSTEM_NXCODEC_NXCODEC_CONTEXT_H
|
||||
#define __APP_SYSTEM_NXCODEC_NXCODEC_CONTEXT_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/videoio.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct nxcodec_context_buf_s
|
||||
{
|
||||
FAR void *addr;
|
||||
size_t length;
|
||||
struct v4l2_buffer buf;
|
||||
bool free;
|
||||
} nxcodec_context_buf_t;
|
||||
|
||||
typedef struct nxcodec_context_s
|
||||
{
|
||||
char filename[PATH_MAX];
|
||||
int fd;
|
||||
enum v4l2_buf_type type;
|
||||
struct v4l2_format format;
|
||||
struct v4l2_fmtdesc fdesc;
|
||||
FAR nxcodec_context_buf_t *buf;
|
||||
int nbuffers;
|
||||
} nxcodec_context_t;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
int nxcodec_context_init(FAR nxcodec_context_t *ctx);
|
||||
int nxcodec_context_set_status(FAR nxcodec_context_t *ctx, uint32_t cmd);
|
||||
int nxcodec_context_enqueue_frame(FAR nxcodec_context_t *ctx);
|
||||
int nxcodec_context_dequeue_frame(FAR nxcodec_context_t *ctx);
|
||||
int nxcodec_context_get_format(FAR nxcodec_context_t *ctx);
|
||||
int nxcodec_context_set_format(FAR nxcodec_context_t *ctx);
|
||||
void nxcodec_context_uninit(FAR nxcodec_context_t *ctx);
|
||||
|
||||
#endif /* __APP_SYSTEM_NXCODEC_NXCODEC_CONTEXT_H */
|
206
system/nxcodec/nxcodec_main.c
Normal file
206
system/nxcodec/nxcodec_main.c
Normal file
@ -0,0 +1,206 @@
|
||||
/****************************************************************************
|
||||
* apps/system/nxcodec/nxcodec_main.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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <poll.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "nxcodec.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const char g_short_options[] = "d:s:hf:i:o:";
|
||||
|
||||
static const struct option g_long_options[] =
|
||||
{
|
||||
{ "device", required_argument, NULL, 'd' },
|
||||
{ "size", required_argument, NULL, 's' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "format", required_argument, NULL, 'f' },
|
||||
{ "infile", required_argument, NULL, 'i' },
|
||||
{ "outfile", required_argument, NULL, 'o' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void usage(FAR const char *progname)
|
||||
{
|
||||
printf("Usage: %s [options]\n\n"
|
||||
"Version 1.3\n"
|
||||
"Options:\n"
|
||||
"-d | --device Video device name\n"
|
||||
"-s | --size Size of stream\n"
|
||||
"-h | --help Print this message\n"
|
||||
"-f | --format Format of stream\n"
|
||||
"-i | --infile Input filename for M2M devices\n"
|
||||
"-o | --outfile Outputs stream to filename\n\n"
|
||||
"eg: nxcodec -d /dev/video1 -s 256x144 \
|
||||
-f H264 -i input.h264 -f YU12 -o output.yuv\n",
|
||||
progname);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* nxcodec_main
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, FAR char **argv)
|
||||
{
|
||||
nxcodec_t codec;
|
||||
int ret;
|
||||
char cc[5] =
|
||||
{
|
||||
0
|
||||
};
|
||||
|
||||
memset(&codec, 0, sizeof(codec));
|
||||
|
||||
while (1)
|
||||
{
|
||||
int idx;
|
||||
int c;
|
||||
|
||||
c = getopt_long(argc, argv, g_short_options, g_long_options, &idx);
|
||||
if (-1 == c)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0: /* getopt_long() flag */
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
memset(codec.devname, 0, sizeof(codec.devname));
|
||||
snprintf(codec.devname, sizeof(codec.devname), "%s", optarg);
|
||||
break;
|
||||
|
||||
case 's' :
|
||||
sscanf(optarg, "%"SCNu32"x%"SCNu32"",
|
||||
&codec.capture.format.fmt.pix.width,
|
||||
&codec.capture.format.fmt.pix.height);
|
||||
|
||||
codec.output.format.fmt.pix.width =
|
||||
codec.capture.format.fmt.pix.width;
|
||||
codec.output.format.fmt.pix.height =
|
||||
codec.capture.format.fmt.pix.height;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
|
||||
case 'f':
|
||||
memset(cc, 0, 5);
|
||||
snprintf(cc, sizeof(cc), "%s", optarg);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
memset(codec.output.filename, 0, sizeof(codec.output.filename));
|
||||
snprintf(codec.output.filename,
|
||||
sizeof(codec.output.filename), "%s", optarg);
|
||||
|
||||
codec.output.format.fmt.pix.pixelformat =
|
||||
v4l2_fourcc(cc[0], cc[1], cc[2], cc[3]);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
memset(codec.capture.filename, 0,
|
||||
sizeof(codec.capture.filename));
|
||||
snprintf(codec.capture.filename,
|
||||
sizeof(codec.capture.filename), "%s", optarg);
|
||||
|
||||
codec.capture.format.fmt.pix.pixelformat =
|
||||
v4l2_fourcc(cc[0], cc[1], cc[2], cc[3]);
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc != optind)
|
||||
{
|
||||
printf("Too few input parameter!\n\n");
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
ret = nxcodec_init(&codec);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = nxcodec_start(&codec);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto end0;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct pollfd pfd =
|
||||
{
|
||||
.events = POLLIN | POLLOUT,
|
||||
.fd = codec.fd,
|
||||
};
|
||||
|
||||
poll(&pfd, 1, -1);
|
||||
|
||||
if (pfd.revents & POLLIN)
|
||||
{
|
||||
if (nxcodec_context_dequeue_frame(&codec.capture) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pfd.revents & POLLOUT)
|
||||
{
|
||||
if (nxcodec_context_enqueue_frame(&codec.output) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nxcodec_stop(&codec);
|
||||
|
||||
end0:
|
||||
nxcodec_uninit(&codec);
|
||||
return ret;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user