add m2m decoder/encoder test

Signed-off-by: yangsen5 <yangsen5@xiaomi.com>
This commit is contained in:
yangsen5 2024-03-05 20:45:08 +08:00 committed by Xiang Xiao
parent 6b9d51793f
commit 9312a74004
8 changed files with 1053 additions and 0 deletions

30
system/nxcodec/Kconfig Normal file
View 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
View 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
View 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
View 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
View 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 */

View 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);
}

View 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 */

View 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;
}