Add v4l2m2m & sim decoder

Signed-off-by: shizhenghui <shizhenghui@xiaomi.com>
This commit is contained in:
shizhenghui
2024-03-21 19:03:16 +08:00
committed by Xiang Xiao
parent 03c756dd74
commit ed1ad1be65
13 changed files with 2205 additions and 2 deletions
+14
View File
@@ -331,6 +331,20 @@ config SIM_CAMERA_DEV_PATH
endif
menu "Simulated v4l2m2m support"
config SIM_VIDEO_DECODER
bool "Video decoder support on sim"
depends on VIDEO
default n
config SIM_VIDEO_DECODER_DEV_PATH
string "Video decoder device path"
depends on SIM_VIDEO_DECODER
default "/dev/video1"
endmenu
menu "Simulated Graphics/Input"
config SIM_X11FB
+6
View File
@@ -250,6 +250,12 @@ ifeq ($(CONFIG_SIM_CAMERA_V4L2),y)
STDLIBS += -lv4l2
endif
ifeq ($(CONFIG_SIM_VIDEO_DECODER),y)
HOSTSRCS += sim_hostdecoder.c
CSRCS += sim_decoder.c
STDLIBS += -lopenh264
endif
COBJS = $(CSRCS:.c=$(OBJEXT))
NUTTXOBJS = $(AOBJS) $(COBJS)
+6
View File
@@ -155,6 +155,12 @@ if(CONFIG_SIM_CAMERA_V4L2)
list(APPEND STDLIBS v4l2)
endif()
if(CONFIG_SIM_VIDEO_DECODER)
list(APPEND HOSTSRCS sim_hostdecoder.c)
list(APPEND SRCS sim_decoder.c)
list(APPEND STDLIBS openh264)
endif()
if(CONFIG_SPINLOCK)
list(APPEND HOSTSRCS sim_testset.c)
endif()
+478
View File
@@ -0,0 +1,478 @@
/****************************************************************************
* arch/sim/src/sim/sim_decoder.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 <errno.h>
#include <string.h>
#include <nuttx/kmalloc.h>
#include <nuttx/video/v4l2_m2m.h>
#include "sim_hostdecoder.h"
#include "sim_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define SIM_DECODER_NAME "sim-h264"
/****************************************************************************
* Private Types
****************************************************************************/
struct sim_decoder_s
{
struct host_decoder_s *decoder;
struct v4l2_format output_fmt;
struct v4l2_format capture_fmt;
struct work_s work;
void *cookie;
bool capture_on;
bool flushing;
};
typedef struct sim_decoder_s sim_decoder_t;
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static int sim_decoder_open(void *cookie, void **priv);
static int sim_decoder_close(void *priv);
static int sim_decoder_capture_streamon(void *priv);
static int sim_decoder_output_streamon(void *priv);
static int sim_decoder_capture_streamoff(void *priv);
static int sim_decoder_output_streamoff(void *priv);
static int sim_decoder_output_available(void *priv);
static int sim_decoder_capture_available(void *priv);
static int sim_decoder_querycap(void *priv,
struct v4l2_capability *cap);
static int sim_decoder_capture_enum_fmt(void *priv,
struct v4l2_fmtdesc *fmt);
static int sim_decoder_output_enum_fmt(void *priv,
struct v4l2_fmtdesc *fmt);
static int sim_decoder_capture_g_fmt(void *priv,
struct v4l2_format *fmt);
static int sim_decoder_output_g_fmt(void *priv,
struct v4l2_format *fmt);
static int sim_decoder_capture_s_fmt(void *priv,
struct v4l2_format *fmt);
static int sim_decoder_output_s_fmt(void *priv,
struct v4l2_format *fmt);
static int sim_decoder_capture_try_fmt(void *priv,
struct v4l2_format *fmt);
static int sim_decoder_output_try_fmt(void *priv,
struct v4l2_format *fmt);
static int sim_decoder_subscribe_event(void *priv,
struct v4l2_event_subscription *sub);
static size_t sim_decoder_capture_g_bufsize(void *priv);
static size_t sim_decoder_output_g_bufsize(void *priv);
static int sim_decoder_process(sim_decoder_t *sim_decoder,
struct v4l2_buffer *dst_buf,
struct v4l2_buffer *src_buf);
static void sim_decoder_work(void *cookie);
/****************************************************************************
* Private Data
****************************************************************************/
static const struct codec_ops_s g_sim_decoder_ops =
{
.open = sim_decoder_open,
.close = sim_decoder_close,
.capture_streamon = sim_decoder_capture_streamon,
.output_streamon = sim_decoder_output_streamon,
.capture_streamoff = sim_decoder_capture_streamoff,
.output_streamoff = sim_decoder_output_streamoff,
.output_available = sim_decoder_output_available,
.capture_available = sim_decoder_capture_available,
.querycap = sim_decoder_querycap,
.capture_enum_fmt = sim_decoder_capture_enum_fmt,
.output_enum_fmt = sim_decoder_output_enum_fmt,
.capture_g_fmt = sim_decoder_capture_g_fmt,
.output_g_fmt = sim_decoder_output_g_fmt,
.capture_s_fmt = sim_decoder_capture_s_fmt,
.output_s_fmt = sim_decoder_output_s_fmt,
.capture_try_fmt = sim_decoder_capture_try_fmt,
.output_try_fmt = sim_decoder_output_try_fmt,
.subscribe_event = sim_decoder_subscribe_event,
.capture_g_bufsize = sim_decoder_capture_g_bufsize,
.output_g_bufsize = sim_decoder_output_g_bufsize,
};
static struct codec_s g_sim_codec_decoder =
{
.ops = &g_sim_decoder_ops,
};
/****************************************************************************
* Private Functions
****************************************************************************/
static int sim_decoder_open(void *cookie, void **priv)
{
sim_decoder_t *sim_decoder;
struct host_decoder_s *decoder;
sim_decoder = kmm_zalloc(sizeof(sim_decoder_t));
if (sim_decoder == NULL)
{
return -ENOMEM;
}
decoder = host_decoder_open();
if (decoder == NULL)
{
kmm_free(sim_decoder);
return -ENOMEM;
}
sim_decoder->decoder = decoder;
sim_decoder->cookie = cookie;
*priv = sim_decoder;
return 0;
}
static int sim_decoder_close(void *priv)
{
sim_decoder_t *sim_decoder = priv;
host_decoder_close(sim_decoder->decoder);
kmm_free(sim_decoder);
return 0;
}
static int sim_decoder_capture_streamon(void *priv)
{
sim_decoder_t *sim_decoder = priv;
sim_decoder->capture_on = true;
work_queue(HPWORK, &sim_decoder->work,
sim_decoder_work, sim_decoder, 0);
return 0;
}
static int sim_decoder_output_streamon(void *priv)
{
sim_decoder_t *sim_decoder = priv;
return host_decoder_streamon(sim_decoder->decoder);
}
static int sim_decoder_capture_streamoff(void *priv)
{
sim_decoder_t *sim_decoder = priv;
sim_decoder->capture_on = false;
return host_decoder_streamoff(sim_decoder->decoder);
}
static int sim_decoder_output_streamoff(void *priv)
{
sim_decoder_t *sim_decoder = priv;
if (!sim_decoder->capture_on)
{
return 0;
}
sim_decoder->flushing = true;
work_queue(HPWORK, &sim_decoder->work,
sim_decoder_work, sim_decoder, 0);
return 0;
}
static int sim_decoder_output_available(void *priv)
{
sim_decoder_t *sim_decoder = priv;
if (sim_decoder->capture_on == false)
{
return 0;
}
work_queue(HPWORK, &sim_decoder->work,
sim_decoder_work, sim_decoder, 0);
return 0;
}
static int sim_decoder_capture_available(void *priv)
{
sim_decoder_t *sim_decoder = priv;
if (sim_decoder->capture_on == false)
{
return 0;
}
work_queue(HPWORK, &sim_decoder->work,
sim_decoder_work, sim_decoder, 0);
return 0;
}
static int sim_decoder_querycap(void *priv,
struct v4l2_capability *cap)
{
strlcpy((char *)cap->driver, SIM_DECODER_NAME, sizeof(cap->driver));
strlcpy((char *)cap->card, SIM_DECODER_NAME, sizeof(cap->card));
cap->capabilities = V4L2_CAP_VIDEO_M2M;
return 0;
}
static int sim_decoder_capture_enum_fmt(void *priv,
struct v4l2_fmtdesc *f)
{
if (f->index >= 1)
{
return -EINVAL;
}
f->pixelformat = V4L2_PIX_FMT_YUV420;
return 0;
}
static int sim_decoder_output_enum_fmt(void *priv,
struct v4l2_fmtdesc *fmt)
{
if (fmt->index >= 1)
{
return -EINVAL;
}
fmt->pixelformat = V4L2_PIX_FMT_H264;
return 0;
}
static int sim_decoder_capture_g_fmt(void *priv,
struct v4l2_format *fmt)
{
sim_decoder_t *sim_decoder = priv;
*fmt = sim_decoder->capture_fmt;
return 0;
}
static int sim_decoder_output_g_fmt(void *priv,
struct v4l2_format *fmt)
{
sim_decoder_t *sim_decoder = priv;
*fmt = sim_decoder->output_fmt;
return 0;
}
static int sim_decoder_capture_s_fmt(void *priv,
struct v4l2_format *fmt)
{
sim_decoder_t *sim_decoder = priv;
size_t sizeimage;
if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
{
sim_decoder->capture_fmt = *fmt;
sizeimage = fmt->fmt.pix.width * fmt->fmt.pix.height * 3 / 2;
sim_decoder->capture_fmt.fmt.pix.sizeimage = sizeimage;
sim_decoder->capture_fmt.fmt.pix.bytesperline = fmt->fmt.pix.width;
return 0;
}
return -EINVAL;
}
static int sim_decoder_output_s_fmt(void *priv,
struct v4l2_format *fmt)
{
sim_decoder_t *sim_decoder = priv;
size_t sizeimage;
if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_H264)
{
sim_decoder->output_fmt = *fmt;
sizeimage = fmt->fmt.pix.width * fmt->fmt.pix.height;
sizeimage = (sizeimage * 3 / 2) / 2 + 128;
sim_decoder->output_fmt.fmt.pix.sizeimage = sizeimage;
return 0;
}
return -EINVAL;
}
static int sim_decoder_capture_try_fmt(void *priv,
struct v4l2_format *fmt)
{
if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
{
return 0;
}
return -EINVAL;
}
static int sim_decoder_output_try_fmt(void *priv,
struct v4l2_format *fmt)
{
if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_H264)
{
return 0;
}
return -EINVAL;
}
static int sim_decoder_subscribe_event(void *priv,
struct v4l2_event_subscription *sub)
{
switch (sub->type)
{
case V4L2_EVENT_EOS:
return OK;
default:
return -EINVAL;
}
}
static size_t sim_decoder_capture_g_bufsize(void *priv)
{
sim_decoder_t *sim_decoder = priv;
if (sim_decoder->capture_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
{
return sim_decoder->capture_fmt.fmt.pix.sizeimage;
}
return 0;
}
static size_t sim_decoder_output_g_bufsize(void *priv)
{
sim_decoder_t *sim_decoder = priv;
if (sim_decoder->output_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_H264)
{
return sim_decoder->output_fmt.fmt.pix.sizeimage;
}
return 0;
}
static int sim_decoder_process(sim_decoder_t *sim_decoder,
struct v4l2_buffer *dst_buf,
struct v4l2_buffer *src_buf)
{
struct v4l2_event event;
uint8_t *src_data = NULL;
uint32_t src_size = 0;
int64_t src_pts = 0;
int64_t dst_pts = 0;
int ret;
if (src_buf != NULL)
{
src_data = (uint8_t *)src_buf->m.userptr;
src_size = src_buf->bytesused;
src_pts = src_buf->timestamp.tv_sec * 1000000 +
src_buf->timestamp.tv_usec;
}
ret = host_decoder_enqueue(sim_decoder->decoder,
src_data, src_pts, src_size);
if (ret >= 0 && src_buf != NULL)
{
codec_output_put_buf(sim_decoder->cookie, src_buf);
}
if (ret < 1)
{
return ret;
}
ret = host_decoder_dequeue(sim_decoder->decoder,
(uint8_t *)dst_buf->m.userptr,
&dst_pts,
&dst_buf->bytesused);
if (ret == 0 && src_buf == NULL)
{
sim_decoder->flushing = false;
dst_buf->flags |= V4L2_BUF_FLAG_LAST;
memset(&event, 0, sizeof(event));
event.type = V4L2_EVENT_EOS;
codec_queue_event(sim_decoder->cookie, &event);
}
dst_buf->timestamp.tv_usec = dst_pts % 1000000;
dst_buf->timestamp.tv_sec = dst_pts / 1000000;
codec_capture_put_buf(sim_decoder->cookie, dst_buf);
return ret;
}
static void sim_decoder_work(void *decoder)
{
sim_decoder_t *sim_decoder = decoder;
struct v4l2_buffer *src_buf;
struct v4l2_buffer *dst_buf;
int ret;
src_buf = codec_output_get_buf(sim_decoder->cookie);
if (src_buf == NULL && !sim_decoder->flushing)
{
return;
}
dst_buf = codec_capture_get_buf(sim_decoder->cookie);
if (dst_buf == NULL)
{
return;
}
ret = sim_decoder_process(decoder, dst_buf, src_buf);
if (ret > 0)
{
work_queue(HPWORK, &sim_decoder->work,
sim_decoder_work, sim_decoder, 0);
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
int sim_decoder_initialize()
{
return codec_register(CONFIG_SIM_VIDEO_DECODER_DEV_PATH,
&g_sim_codec_decoder);
}
+205
View File
@@ -0,0 +1,205 @@
/****************************************************************************
* arch/sim/src/sim/sim_hostdecoder.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 <stdlib.h>
#include <string.h>
#include <errno.h>
#include <syslog.h>
#include <wels/codec_api.h>
#include <wels/codec_app_def.h>
#include "sim_hostdecoder.h"
/****************************************************************************
* Private Types
****************************************************************************/
struct host_decoder_s
{
ISVCDecoder *dec;
SBufferInfo bufinfo;
uint8_t *pdst[4];
int remaining_frames;
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
struct host_decoder_s *host_decoder_open(void)
{
struct host_decoder_s *decoder;
decoder = calloc(1, sizeof(struct host_decoder_s));
if (decoder == NULL)
{
syslog(LOG_ERR, "Init host decoder failed\n");
}
return decoder;
}
int host_decoder_close(struct host_decoder_s *decoder)
{
free(decoder);
return 0;
}
int host_decoder_streamon(struct host_decoder_s *decoder)
{
SDecodingParam param;
int level = WELS_LOG_RESV;
int ret;
memset(&param, 0, sizeof(SDecodingParam));
param.eEcActiveIdc = ERROR_CON_DISABLE;
param.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
ret = WelsCreateDecoder(&decoder->dec);
if (ret < 0)
{
syslog(LOG_ERR, "Failed to create decoder\n");
return ret;
}
(*decoder->dec)->SetOption(decoder->dec,
DECODER_OPTION_TRACE_LEVEL,
&level);
ret = (*decoder->dec)->Initialize(decoder->dec, &param);
if (ret < 0)
{
syslog(LOG_ERR, "Failed to initialize decoder\n");
WelsDestroyDecoder(decoder->dec);
}
return ret;
}
int host_decoder_streamoff(struct host_decoder_s *decoder)
{
(*decoder->dec)->Uninitialize(decoder->dec);
WelsDestroyDecoder(decoder->dec);
decoder->remaining_frames = 0;
return 0;
}
int host_decoder_enqueue(struct host_decoder_s *decoder,
void *data, int64_t pts, int size)
{
DECODING_STATE state;
memset(&decoder->bufinfo, 0, sizeof(SBufferInfo));
memset(decoder->pdst, 0, sizeof(decoder->pdst));
if (decoder->remaining_frames == 0)
{
/* When data is NULL and remaining_frames has
* not been assigned, call DecodeFrame2 to obtain
* the pending buffer.
*/
decoder->bufinfo.uiInBsTimeStamp = pts;
state = (*decoder->dec)->DecodeFrame2(decoder->dec,
data,
size,
decoder->pdst,
&decoder->bufinfo);
if (state != dsErrorFree)
{
syslog(LOG_ERR, "hostdec - decode failed 0x%04x\n", state);
return -EINVAL;
}
if (data == NULL)
{
(*decoder->dec)->GetOption(decoder->dec,
DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER,
&decoder->remaining_frames);
}
}
else
{
/* When remaining_frames is assigned and greater than
* zero, call FlushFrame to get the last buffers.
*/
state = (*decoder->dec)->FlushFrame(decoder->dec,
decoder->pdst,
&decoder->bufinfo);
if (state != dsErrorFree)
{
syslog(LOG_ERR, "hostdec - flush failed 0x%04x\n", state);
return -EINVAL;
}
decoder->remaining_frames--;
}
return decoder->bufinfo.iBufferStatus;
}
int host_decoder_dequeue(struct host_decoder_s *decoder,
void *data, int64_t *pts, uint32_t *size)
{
uint8_t *dst_addr = data;
int plane;
for (plane = 0; plane < 3; plane++)
{
uint8_t *src_addr = decoder->pdst[plane];
int width = decoder->bufinfo.UsrData.sSystemBuffer.iWidth;
int height = decoder->bufinfo.UsrData.sSystemBuffer.iHeight;
int stride = decoder->bufinfo.UsrData.sSystemBuffer.iStride[0];
int row;
if (plane > 0)
{
/* UV plane stride is iStride[1] */
width = width / 2;
height = height / 2;
stride = decoder->bufinfo.UsrData.sSystemBuffer.iStride[1];
}
for (row = 0; row < height; row++)
{
memcpy(dst_addr, src_addr, width);
src_addr += stride;
dst_addr += width;
}
}
*pts = decoder->bufinfo.uiOutYuvTimeStamp;
*size = decoder->bufinfo.UsrData.sSystemBuffer.iWidth *
decoder->bufinfo.UsrData.sSystemBuffer.iHeight * 3 / 2;
return decoder->remaining_frames;
}
+50
View File
@@ -0,0 +1,50 @@
/****************************************************************************
* arch/sim/src/sim/sim_hostdecoder.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 __ARCH_SIM_SRC_SIM_SIM_HOSTDECODER_H
#define __ARCH_SIM_SRC_SIM_SIM_HOSTDECODER_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
/****************************************************************************
* Public Types
****************************************************************************/
struct host_decoder_s;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
struct host_decoder_s *host_decoder_open(void);
int host_decoder_close(struct host_decoder_s *decoder);
int host_decoder_streamon(struct host_decoder_s *decoder);
int host_decoder_streamoff(struct host_decoder_s *decoder);
int host_decoder_enqueue(struct host_decoder_s *decoder,
void *data, int64_t pts, int size);
int host_decoder_dequeue(struct host_decoder_s *decoder,
void *data, int64_t *pts, uint32_t *size);
#endif /* __ARCH_SIM_SRC_SIM_SIM_HOSTDECODER_H */
+4
View File
@@ -306,6 +306,10 @@ void up_initialize(void)
sim_usbhost_initialize();
#endif
#ifdef CONFIG_SIM_VIDEO_DECODER
sim_decoder_initialize();
#endif
kthread_create("loop_task", CONFIG_SIM_LOOPTASK_PRIORITY,
CONFIG_DEFAULT_TASK_STACKSIZE,
sim_loop_task, NULL);
+4
View File
@@ -435,6 +435,10 @@ int sim_camera_initialize(void);
void sim_camera_loop(void);
#endif
#ifdef CONFIG_SIM_VIDEO_DECODER
int sim_decoder_initialize(void);
#endif
/* sim_usbdev.c *************************************************************/
#ifdef CONFIG_SIM_USB_DEV
+1 -1
View File
@@ -29,7 +29,7 @@ if(CONFIG_DRIVERS_VIDEO)
endif()
if(CONFIG_VIDEO_STREAM)
list(APPEND SRCS v4l2_core.c video_framebuff.c v4l2_cap.c)
list(APPEND SRCS v4l2_core.c video_framebuff.c v4l2_cap.c v4l2_m2m.c)
endif()
# These video drivers depend on I2C support
+1 -1
View File
@@ -27,7 +27,7 @@ ifeq ($(CONFIG_VIDEO_FB),y)
endif
ifeq ($(CONFIG_VIDEO_STREAM),y)
CSRCS += v4l2_core.c video_framebuff.c v4l2_cap.c
CSRCS += v4l2_core.c video_framebuff.c v4l2_cap.c v4l2_m2m.c
endif
# These video drivers depend on I2C support
File diff suppressed because it is too large Load Diff
+307
View File
@@ -0,0 +1,307 @@
/****************************************************************************
* include/nuttx/video/v4l2_m2m.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 __INCLUDE_NUTTX_VIDEO_V4L2_M2M_H
#define __INCLUDE_NUTTX_VIDEO_V4L2_M2M_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/videoio.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Method access helper macros */
#define CODEC_OPEN(codec, cookie, priv) \
((codec)->ops->open ? \
(codec)->ops->open(cookie, priv) : -ENOTTY)
#define CODEC_CLOSE(codec, priv) \
((codec)->ops->close ? \
(codec)->ops->close(priv) : -ENOTTY)
#define CODEC_CAPTURE_STREAMON(codec, priv) \
((codec)->ops->capture_streamon ? \
(codec)->ops->capture_streamon(priv) : -ENOTTY)
#define CODEC_OUTPUT_STREAMON(codec, priv) \
((codec)->ops->output_streamon ? \
(codec)->ops->output_streamon(priv) : -ENOTTY)
#define CODEC_CAPTURE_STREAMOFF(codec, priv) \
((codec)->ops->capture_streamoff ? \
(codec)->ops->capture_streamoff(priv) : -ENOTTY)
#define CODEC_OUTPUT_STREAMOFF(codec, priv) \
((codec)->ops->output_streamoff ? \
(codec)->ops->output_streamoff(priv) : -ENOTTY)
#define CODEC_CAPTURE_AVAILABLE(codec, priv) \
((codec)->ops->capture_available ? \
(codec)->ops->capture_available(priv) : 0)
#define CODEC_OUTPUT_AVAILABLE(codec, priv) \
((codec)->ops->output_available ? \
(codec)->ops->output_available(priv) : -ENOTTY)
#define CODEC_QUERYCAP(codec, priv, cap) \
((codec)->ops->querycap ? \
(codec)->ops->querycap(priv, cap) : -ENOTTY)
#define CODEC_CAPTURE_ENUM_FMT(codec, priv, fmt) \
((codec)->ops->capture_enum_fmt ? \
(codec)->ops->capture_enum_fmt(priv, fmt) : -ENOTTY)
#define CODEC_OUTPUT_ENUM_FMT(codec, priv, fmt) \
((codec)->ops->output_enum_fmt ? \
(codec)->ops->output_enum_fmt(priv, fmt) : -ENOTTY)
#define CODEC_CAPTURE_G_FMT(codec, priv, fmt) \
((codec)->ops->capture_g_fmt ? \
(codec)->ops->capture_g_fmt(priv, fmt) : -ENOTTY)
#define CODEC_OUTPUT_G_FMT(codec, priv, fmt) \
((codec)->ops->output_g_fmt ? \
(codec)->ops->output_g_fmt(priv, fmt) : -ENOTTY)
#define CODEC_CAPTURE_S_FMT(codec, priv, fmt) \
((codec)->ops->capture_s_fmt ? \
(codec)->ops->capture_s_fmt(priv, fmt) : -ENOTTY)
#define CODEC_OUTPUT_S_FMT(codec, priv, fmt) \
((codec)->ops->output_s_fmt ? \
(codec)->ops->output_s_fmt(priv, fmt) : -ENOTTY)
#define CODEC_CAPTURE_TRY_FMT(codec, priv, fmt) \
((codec)->ops->capture_try_fmt ? \
(codec)->ops->capture_try_fmt(priv, fmt) : -ENOTTY)
#define CODEC_OUTPUT_TRY_FMT(codec, priv, fmt) \
((codec)->ops->output_try_fmt ? \
(codec)->ops->output_try_fmt(priv, fmt) : -ENOTTY)
#define CODEC_CAPTURE_G_PARM(codec, priv, parm) \
((codec)->ops->capture_g_parm ? \
(codec)->ops->capture_g_parm(priv, parm) : -ENOTTY)
#define CODEC_OUTPUT_G_PARM(codec, priv, parm) \
((codec)->ops->output_g_parm ? \
(codec)->ops->output_g_parm(priv, parm) : -ENOTTY)
#define CODEC_CAPTURE_S_PARM(codec, priv, parm) \
((codec)->ops->capture_s_parm ? \
(codec)->ops->capture_s_parm(priv, parm) : -ENOTTY)
#define CODEC_OUTPUT_S_PARM(codec, priv, parm) \
((codec)->ops->output_s_parm ? \
(codec)->ops->output_s_parm(priv, parm) : -ENOTTY)
#define CODEC_G_EXT_CTRLS(codec, priv, ctrls) \
((codec)->ops->g_ext_ctrls ? \
(codec)->ops->g_ext_ctrls(priv, ctrls) : -ENOTTY)
#define CODEC_S_EXT_CTRLS(codec, priv, ctrls) \
((codec)->ops->s_ext_ctrls ? \
(codec)->ops->s_ext_ctrls(priv, ctrls) : -ENOTTY)
#define CODEC_CAPTURE_G_SELECTION(codec, priv, clip) \
((codec)->ops->capture_g_selection ? \
(codec)->ops->capture_g_selection(priv, clip) : -ENOTTY)
#define CODEC_OUTPUT_G_SELECTION(codec, priv, clip) \
((codec)->ops->output_g_selection ? \
(codec)->ops->output_g_selection(priv, clip) : -ENOTTY)
#define CODEC_CAPTURE_S_SELECTION(codec, priv, clip) \
((codec)->ops->capture_s_selection ? \
(codec)->ops->capture_s_selection(priv, clip) : -ENOTTY)
#define CODEC_OUTPUT_S_SELECTION(codec, priv, clip) \
((codec)->ops->output_s_selection ? \
(codec)->ops->output_s_selection(priv, clip) : -ENOTTY)
#define CODEC_CAPTURE_CROPCAP(codec, priv, cropcap) \
((codec)->ops->capture_cropcap ? \
(codec)->ops->capture_cropcap(priv, cropcap) : -ENOTTY)
#define CODEC_OUTPUT_CROPCAP(codec, priv, cropcap) \
((codec)->ops->output_cropcap ? \
(codec)->ops->output_cropcap(priv, cropcap) : -ENOTTY)
#define CODEC_DQEVENT(codec, priv, event) \
((codec)->ops->dqevent ? \
(codec)->ops->dqevent(priv, event) : -ENOTTY)
#define CODEC_SUBSCRIBE_EVENT(codec, priv, sub) \
((codec)->ops->subscribe_event ? \
(codec)->ops->subscribe_event(priv, sub) : -ENOTTY)
#define CODEC_DECODER_CMD(codec, priv, cmd) \
((codec)->ops->decoder_cmd ? \
(codec)->ops->decoder_cmd(priv, cmd) : -ENOTTY)
#define CODEC_ENCODER_CMD(codec, priv, cmd) \
((codec)->ops->encoder_cmd ? \
(codec)->ops->encoder_cmd(priv, cmd) : -ENOTTY)
#define CODEC_CAPTURE_G_BUFSIZE(codec, priv) \
((codec)->ops->capture_g_bufsize ? \
(codec)->ops->capture_g_bufsize(priv) : -ENOTTY)
#define CODEC_OUTPUT_G_BUFSIZE(codec, priv) \
((codec)->ops->output_g_bufsize ? \
(codec)->ops->output_g_bufsize(priv) : -ENOTTY)
/****************************************************************************
* Public Types
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
struct codec_s;
struct codec_ops_s
{
CODE int (*open)(FAR void *cookie, FAR void **priv);
CODE int (*close)(FAR void *priv);
CODE int (*capture_streamon)(FAR void *priv);
CODE int (*output_streamon)(FAR void *priv);
CODE int (*capture_streamoff)(FAR void *priv);
CODE int (*output_streamoff)(FAR void *priv);
CODE int (*capture_available)(FAR void *priv);
CODE int (*output_available)(FAR void *priv);
/* VIDIOC_QUERYCAP handler */
CODE int (*querycap)(FAR void *priv,
FAR struct v4l2_capability *cap);
/* VIDIOC_ENUM_FMT handlers */
CODE int (*capture_enum_fmt)(FAR void *priv,
FAR struct v4l2_fmtdesc *fmt);
CODE int (*output_enum_fmt)(FAR void *priv,
FAR struct v4l2_fmtdesc *fmt);
/* VIDIOC_G_FMT handlers */
CODE int (*capture_g_fmt)(FAR void *priv,
FAR struct v4l2_format *fmt);
CODE int (*output_g_fmt)(FAR void *priv,
FAR struct v4l2_format *fmt);
/* VIDIOC_S_FMT handlers */
CODE int (*capture_s_fmt)(FAR void *priv,
FAR struct v4l2_format *fmt);
CODE int (*output_s_fmt)(FAR void *priv,
FAR struct v4l2_format *fmt);
/* VIDIOC_TRY_FMT handlers */
CODE int (*capture_try_fmt)(FAR void *priv,
FAR struct v4l2_format *fmt);
CODE int (*output_try_fmt)(FAR void *priv,
FAR struct v4l2_format *fmt);
/* Buffer handlers */
CODE size_t (*capture_g_bufsize)(FAR void *priv);
CODE size_t (*output_g_bufsize)(FAR void *priv);
/* Stream type-dependent parameter ioctls */
CODE int (*capture_g_parm)(FAR void *priv,
FAR struct v4l2_streamparm *parm);
CODE int (*output_g_parm)(FAR void *priv,
FAR struct v4l2_streamparm *parm);
CODE int (*capture_s_parm)(FAR void *priv,
FAR struct v4l2_streamparm *parm);
CODE int (*output_s_parm)(FAR void *priv,
FAR struct v4l2_streamparm *parm);
/* Control handlers */
CODE int (*g_ext_ctrls)(FAR void *priv,
FAR struct v4l2_ext_controls *ctrls);
CODE int (*s_ext_ctrls)(FAR void *priv,
FAR struct v4l2_ext_controls *ctrls);
/* Crop ioctls */
CODE int (*capture_g_selection)(FAR void *priv,
FAR struct v4l2_selection *clip);
CODE int (*output_g_selection)(FAR void *priv,
FAR struct v4l2_selection *clip);
CODE int (*capture_s_selection)(FAR void *priv,
FAR struct v4l2_selection *clip);
CODE int (*output_s_selection)(FAR void *priv,
FAR struct v4l2_selection *clip);
CODE int (*capture_cropcap)(FAR void *priv,
FAR struct v4l2_cropcap *cropcap);
CODE int (*output_cropcap)(FAR void *priv,
FAR struct v4l2_cropcap *cropcap);
/* Event handlers */
CODE int (*subscribe_event)(FAR void *priv,
FAR struct v4l2_event_subscription *sub);
/* Command handlers */
CODE int (*decoder_cmd)(FAR void *priv,
FAR struct v4l2_decoder_cmd *cmd);
CODE int (*encoder_cmd)(FAR void *priv,
FAR struct v4l2_encoder_cmd *cmd);
};
struct codec_s
{
FAR const struct codec_ops_s *ops;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
int codec_register(FAR const char *devpath, FAR struct codec_s *codec);
int codec_unregister(FAR const char *devpath);
FAR struct v4l2_buffer *codec_output_get_buf(FAR void *cookie);
FAR struct v4l2_buffer *codec_capture_get_buf(FAR void *cookie);
int codec_output_put_buf(FAR void *cookie, FAR struct v4l2_buffer *buf);
int codec_capture_put_buf(FAR void *cookie, FAR struct v4l2_buffer *buf);
int codec_queue_event(FAR void *cookie, FAR struct v4l2_event *evt);
#ifdef __cplusplus
}
#endif
#endif /* __INCLUDE_NUTTX_VIDEO_V4L2_M2M_H */
+29
View File
@@ -451,6 +451,35 @@ static const char *g_white_content_list[] =
"CurrentTime",
"XUnmapWindow",
/* Ref:
* nuttx/arch/sim/src/sim_hostdecoder.*
*/
"ISVCDecoder",
"SBufferInfo",
"SDecodingParam",
"eEcActiveIdc",
"sVideoProperty",
"eVideoBsType",
"cmResultSuccess",
"uiInBsTimeStamp",
"dsErrorFree",
"iBufferStatus",
"UsrData",
"sSystemBuffer",
"iWidth",
"iHeight",
"iStride",
"uiOutYuvTimeStamp",
"WelsCreateDecoder",
"WelsDestroyDecoder",
"Initialize",
"Uninitialize",
"DecodeFrame2",
"FlushFrame",
"SetOption",
"GetOption",
/* Ref:
* sim/posix/sim_deviceimage.c
*/