From 8c1afe595e98f4aef8320b4c16990256bcd36298 Mon Sep 17 00:00:00 2001 From: "yumei.jia" Date: Thu, 6 Aug 2026 06:24:22 +0000 Subject: [PATCH] encoder: CB1 add v4l2 tahoe_test. [1/1] PD#SWPL-284054 Problem: add v4l2 tahoe_test Solution: add v4l2 tahoe_test Verify: a9 Change-Id: I2e7464b52943e0cebecb52c7043c8ffcee0d5a4b Signed-off-by: yumei.jia --- amvenc/amvenc_lib/amvenc.c | 5 +- amvenc_tahoe/tahoe_enc/libvptahoe_codec.c | 761 +++++++++++++++++--- amvenc_tahoe/tahoe_enc/libvptahoe_codec.h | 6 +- amvenc_tahoe/tahoe_enc/libvptahoe_wrapper.c | 110 ++- amvenc_tahoe/tahoe_enc/tahoe.h | 5 + amvenc_tahoe/test.c | 129 ++-- 6 files changed, 862 insertions(+), 154 deletions(-) diff --git a/amvenc/amvenc_lib/amvenc.c b/amvenc/amvenc_lib/amvenc.c index 946523f..57dabfe 100644 --- a/amvenc/amvenc_lib/amvenc.c +++ b/amvenc/amvenc_lib/amvenc.c @@ -17,6 +17,7 @@ #define AMVENC_265_DEVICE "/dev/HevcEnc" #define AMVENC_VERS_DEVICE "/dev/vc8000" #define AMVENC_TAHOE_DEVICE "/dev/tahoe" +#define AMVENC_TAHOE_V4L_DEVICE "/dev/video90" typedef enum amvenc_hw_e { AMVENC_UNKNOWN, @@ -133,7 +134,7 @@ int selectHW(amvenc_codec_id_t codec_id, int *hw_type) VLOG(DEBUG, "amvenc_vers present"); ret = 0; } - else if (access(AMVENC_TAHOE_DEVICE, F_OK ) != -1) { + else if ((access(AMVENC_TAHOE_DEVICE, F_OK ) != -1) || (access(AMVENC_TAHOE_V4L_DEVICE, F_OK )!= -1)) { *hw_type = AMVENC_TAHOE; VLOG(DEBUG, "amvenc_tahoe present"); ret = 0; @@ -158,7 +159,7 @@ int selectHW(amvenc_codec_id_t codec_id, int *hw_type) VLOG(DEBUG, "amvenc_vers present"); ret = 0; } - else if (access(AMVENC_TAHOE_DEVICE, F_OK ) != -1) { + else if ((access(AMVENC_TAHOE_DEVICE, F_OK ) != -1) || (access(AMVENC_TAHOE_V4L_DEVICE, F_OK )!= -1)) { *hw_type = AMVENC_TAHOE; VLOG(DEBUG, "amvenc_tahoe present"); ret = 0; diff --git a/amvenc_tahoe/tahoe_enc/libvptahoe_codec.c b/amvenc_tahoe/tahoe_enc/libvptahoe_codec.c index af192b8..2740b39 100644 --- a/amvenc_tahoe/tahoe_enc/libvptahoe_codec.c +++ b/amvenc_tahoe/tahoe_enc/libvptahoe_codec.c @@ -41,10 +41,371 @@ #include "tahoe_register.h" #include #include +#include +#include +#include #define MAX_FRAME_WINDOW (120) venc_info_t s_venc_info; +#include // open(), O_RDWR, O_RDONLY... +#include // close(), read(), write() +#include + + +struct v4l2_buffer *src_buf_info = NULL; +struct v4l2_buffer *dst_buf_info = NULL; +unsigned char **src_buffers = NULL; +unsigned char **dst_buffers = NULL; +int *src_buf_lengths = NULL; +int *dst_buf_lengths = NULL; +int src_buf_count = 0, dst_buf_count = 0; +//int frame_count = 0; +//struct v4l2_buffer src_buf, dst_buf; +struct timespec ts_start, ts_end; +#define CLEAR(x) memset(&(x), 0, sizeof(x)) + + +void query_and_set_control(int fd, unsigned int id, int value) { + struct v4l2_queryctrl query; + struct v4l2_control ctrl; + + CLEAR(query); + query.id = id; + + if (ioctl(fd, VIDIOC_QUERYCTRL, &query) == 0) { + printf("[%s] range: %d - %d, default: %d, step: %d\n", + query.name, query.minimum, query.maximum, query.default_value, query.step); + + if (value >= query.minimum && value <= query.maximum) { + CLEAR(ctrl); + ctrl.id = id; + ctrl.value = value; + if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) == 0) { + printf("[%s] set to %d successfully\n", query.name, value); + } else { + perror("VIDIOC_S_CTRL failed"); + } + } else { + printf("[%s] value %d out of range [%d, %d], skipping\n", + query.name, value, query.minimum, query.maximum); + } + } else { + printf("Control 0x%08x not supported\n", id); + } +} + +void setup_encoder_params(int fd, handle_t *encode_info) { + printf("\n=== Setting up encoder parameters ===\n"); + + // GOP + query_and_set_control(fd, V4L2_CID_MPEG_VIDEO_GOP_SIZE, encode_info->enc_gop); + + // Bitrate + query_and_set_control(fd, V4L2_CID_MPEG_VIDEO_BITRATE, encode_info->enc_bitrate); + + // H.264 Profile + if (encode_info->profile == 3 && encode_info->enc_fmt == CODEC_ID_H264) + query_and_set_control(fd, V4L2_CID_MPEG_VIDEO_H264_PROFILE, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); +// +// // H.264 Level + if (encode_info->enc_fmt == CODEC_ID_H264) + query_and_set_control(fd, V4L2_CID_MPEG_VIDEO_H264_LEVEL, V4L2_MPEG_VIDEO_H264_LEVEL_4_0); +// + if (encode_info->profile == 3 && encode_info->enc_fmt == CODEC_ID_H265) + query_and_set_control(fd, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN); + + if (encode_info->enc_fmt == CODEC_ID_H265) + query_and_set_control(fd, V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, V4L2_MPEG_VIDEO_HEVC_LEVEL_4); +// query_and_set_control(fd, V4L2_CID_MPEG_VIDEO_HEVC_TIER_FLAG, +// V4L2_MPEG_VIDEO_HEVC_TIER_MAIN); +} + +int setup_src_format_mplane(int fd, handle_t *encode_info,int plane_num) { + struct v4l2_format fmt; + CLEAR(fmt); + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.width = encode_info->enc_width; + fmt.fmt.pix_mp.height = encode_info->enc_height; + if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_NV12) + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; + else if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_NV21) + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV21; + else if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_YUV420_PLANAR) + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUV420; + else if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_RGB888) + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_RGB24; + #if 0 + else if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_RGBA8888) + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_RGBA32; + #endif + fmt.fmt.pix_mp.field = V4L2_FIELD_NONE; + fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; + + printf("setup_src_format_mplane fmt input:%d\n",encode_info->mfdin_input_fmt); + if (encode_info->current_mode == DMA_TYPE) { //dmabuf + if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_NV12) + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; + else if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_NV21) + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV21M; + else if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_YUV420_PLANAR) + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUV420M; + fmt.fmt.pix_mp.num_planes = plane_num; + if (1 == fmt.fmt.pix_mp.num_planes) { //rgb rgba? + fmt.fmt.pix_mp.plane_fmt[0].bytesperline = encode_info->enc_width; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = encode_info->enc_width * encode_info->enc_height * 3 / 2; + } + else if (2 == fmt.fmt.pix_mp.num_planes) { + fmt.fmt.pix_mp.plane_fmt[0].bytesperline = encode_info->enc_width; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = encode_info->enc_width * encode_info->enc_height; + + fmt.fmt.pix_mp.plane_fmt[1].bytesperline = encode_info->enc_width; + fmt.fmt.pix_mp.plane_fmt[1].sizeimage = encode_info->enc_width * encode_info->enc_height / 2; + } + else if (3 == fmt.fmt.pix_mp.num_planes){ + fmt.fmt.pix_mp.plane_fmt[0].bytesperline = encode_info->enc_width; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = encode_info->enc_width * encode_info->enc_height; + + fmt.fmt.pix_mp.plane_fmt[1].bytesperline = encode_info->enc_width; + fmt.fmt.pix_mp.plane_fmt[1].sizeimage = encode_info->enc_width * encode_info->enc_height / 4; + + fmt.fmt.pix_mp.plane_fmt[2].bytesperline = encode_info->enc_width; + fmt.fmt.pix_mp.plane_fmt[2].sizeimage = encode_info->enc_width * encode_info->enc_height / 4; + } + } + else { //mmap + fmt.fmt.pix_mp.num_planes = 1; + if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_RGB888) { + fmt.fmt.pix_mp.plane_fmt[0].bytesperline = encode_info->enc_width * 3; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = encode_info->enc_width * encode_info->enc_height * 3; + } + else if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_RGBA8888) { + fmt.fmt.pix_mp.plane_fmt[0].bytesperline = encode_info->enc_width * 4; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = encode_info->enc_width * encode_info->enc_height * 4; + } + else { + fmt.fmt.pix_mp.plane_fmt[0].bytesperline = encode_info->enc_width; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = encode_info->enc_width * encode_info->enc_height * 3 / 2; + } + } + + printf("sizeimage:%d %d\n",fmt.fmt.pix_mp.plane_fmt[0].sizeimage,fmt.fmt.pix_mp.plane_fmt[1].sizeimage); + + if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { + perror("VIDIOC_S_FMT (src) failed"); + return -1; + } + + printf("Source format (MPLANE): %dx%d, pixelformat: %c%c%c%c, planes: %d\n", + fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, + fmt.fmt.pix_mp.pixelformat & 0xFF, + (fmt.fmt.pix_mp.pixelformat >> 8) & 0xFF, + (fmt.fmt.pix_mp.pixelformat >> 16) & 0xFF, + (fmt.fmt.pix_mp.pixelformat >> 24) & 0xFF, + fmt.fmt.pix_mp.num_planes); + + return 0; +} + +int setup_dst_format_mplane(int fd, handle_t *encode_info) { + struct v4l2_format fmt; + CLEAR(fmt); + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.width = encode_info->enc_width; + fmt.fmt.pix_mp.height = encode_info->enc_height; + if (encode_info->enc_fmt == CODEC_ID_H264) + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; + else if (encode_info->enc_fmt == CODEC_ID_H265) + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_HEVC; + fmt.fmt.pix_mp.field = V4L2_FIELD_NONE; + fmt.fmt.pix_mp.num_planes = 1; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = 5*1024*1024; + + if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { + perror("VIDIOC_S_FMT (dst) failed"); + return -1; + } + + printf("Destination format (MPLANE): %dx%d, pixelformat: %c%c%c%c, planes: %d\n", + fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, + fmt.fmt.pix_mp.pixelformat & 0xFF, + (fmt.fmt.pix_mp.pixelformat >> 8) & 0xFF, + (fmt.fmt.pix_mp.pixelformat >> 16) & 0xFF, + (fmt.fmt.pix_mp.pixelformat >> 24) & 0xFF, + fmt.fmt.pix_mp.num_planes); + + return 0; +} + +int setup_buffers_mplane(int fd, int type, int count, + struct v4l2_buffer **buf_info, + unsigned char ***buffers, + int **buf_lengths, + int *num_buffers,enum v4l2_memory memory_type) { + struct v4l2_requestbuffers req; + CLEAR(req); + req.count = count; + req.type = type; + //req.memory = V4L2_MEMORY_MMAP; + + if (0 != memory_type) { + req.memory = memory_type; + } + else { //by default + req.memory = V4L2_MEMORY_MMAP; + } + + if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) { + perror("VIDIOC_REQBUFS failed"); + return -1; + } + + *num_buffers = req.count; + printf("Allocated %d buffers for type %d\n", req.count, type); + + if (req.count == 0) { + printf("No buffers allocated\n"); + return -1; + } + + *buf_info = calloc(req.count, sizeof(struct v4l2_buffer)); + *buffers = calloc(req.count, sizeof(unsigned char *)); + *buf_lengths = calloc(req.count, sizeof(int)); + + if (!*buf_info || !*buffers || !*buf_lengths) { + perror("calloc failed"); + return -1; + } + + for (int i = 0; i < req.count; i++) { + struct v4l2_buffer buf; + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + + CLEAR(buf); + buf.type = type; + //buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + buf.length = VIDEO_MAX_PLANES; +// buf.m.planes = planes; + buf.m.planes = calloc(VIDEO_MAX_PLANES, + sizeof(struct v4l2_plane)); + + if (0 != memory_type) { + buf.memory = memory_type; + } + else { //by default + buf.memory = V4L2_MEMORY_MMAP; + } + + if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) { + perror("VIDIOC_QUERYBUF failed"); + return -1; + } + + memcpy(&((*buf_info)[i]), &buf, sizeof(struct v4l2_buffer)); + + (*buf_lengths)[i] = 0; + for (int p = 0; p < buf.length; p++) { + int plane_size = buf.m.planes[p].length; + (*buf_lengths)[i] += plane_size; + + printf("Buffer %d, plane %d: offset=0x%08x, length=%d\n", + i, p, buf.m.planes[p].m.mem_offset, plane_size); + + if ((p == 0) && (buf.memory == V4L2_MEMORY_MMAP)) { + (*buffers)[i] = mmap(NULL, plane_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, fd, + buf.m.planes[p].m.mem_offset); + if ((*buffers)[i] == MAP_FAILED) { + perror("mmap failed"); + return -1; + } + printf("Buffer %d mapped at %p, size %d\n", + i, (*buffers)[i], plane_size); + } + } + } + + return 0; +} + +void detectV4l2Support(handle_t *encode_info) { + if ((access("/dev/video90", F_OK ) != -1)) { + encode_info->v4l2_enable = true; + VLOG(ERR, "v4l2 component present"); + return; + } + return; +} + + + +int queue_buffer_mplane(int fd, struct v4l2_buffer *buf) { + if (ioctl(fd, VIDIOC_QBUF, buf) < 0) { + perror("VIDIOC_QBUF failed"); + return -1; + } + return 0; +} + +int dequeue_buffer_mplane(int fd, int type, struct v4l2_buffer *buf, struct v4l2_plane *planes,enum v4l2_memory memory_type) { +// struct v4l2_plane planes[VIDEO_MAX_PLANES]; + CLEAR(*buf); + memset(planes, 0, sizeof(struct v4l2_plane) * VIDEO_MAX_PLANES); + buf->type = type; + if (0 != memory_type) { + buf->memory = memory_type; + } + else { + buf->memory = V4L2_MEMORY_MMAP; + } + buf->length = VIDEO_MAX_PLANES; + buf->m.planes = planes; + if (ioctl(fd, VIDIOC_DQBUF, buf) < 0) { + if (errno == EAGAIN) { + return -EAGAIN; + } + perror("VIDIOC_DQBUF failed"); + return -1; + } + + return 0; +} + +int stream_on(int fd, int type) { + enum v4l2_buf_type buf_type = type; + if (ioctl(fd, VIDIOC_STREAMON, &buf_type) < 0) { + perror("VIDIOC_STREAMON failed"); + return -1; + } + return 0; +} + +int stream_off(int fd, int type) { + enum v4l2_buf_type buf_type = type; + if (ioctl(fd, VIDIOC_STREAMOFF, &buf_type) < 0) { + perror("VIDIOC_STREAMOFF failed"); + return -1; + } + return 0; +} + +void print_frame_info(struct v4l2_buffer *buf, const char *tag) { + printf("[%s] Buffer %d, type=%d, bytesused=", tag, buf->index, buf->type); + if (buf->length > 0 && buf->m.planes) { + int total = 0; + for (int p = 0; p < buf->length; p++) { + total += buf->m.planes[p].bytesused; + } + printf("%d", total); + } else { + printf("%d", buf->bytesused); + } + printf(", flags=0x%x\n", buf->flags); +} + + int get_header(handle_t *handle, unsigned char *pHeader, unsigned int *pLength) { venc_info_t *venc = &s_venc_info; @@ -116,32 +477,77 @@ int get_header(handle_t *handle, unsigned char *pHeader, unsigned int *pLength) return 0; } + int get_bsbframe(handle_t *handle, unsigned char *buffer, unsigned int *buf_nal_size, signed char *frame_type) { - venc_info_t *venc = &s_venc_info; - unsigned int esaddr_offset = 0; - unsigned long esPhyAddr; - int eslength; - unsigned long espVirAddr = 0; - unsigned long slice_header_length = 0; - int length_cp = 0; - - slice_header_length = handle->enc_es.slice_header_length; - esPhyAddr = handle->enc_es.esPhyAddr; - eslength = handle->enc_es.eslength; - esaddr_offset = esPhyAddr - venc->common_buffer[handle->chn_id].phys_addr; - espVirAddr = venc->common_buffer[handle->chn_id].virt_addr + esaddr_offset; - VLOG(INFO,"[%s][%d]offset:0x%x\n", __func__, __LINE__, slice_header_length); - VLOG(INFO,"[%s][%d]esPhyAddr:0x%lx\n", __func__, __LINE__, esPhyAddr); - VLOG(INFO,"[%s][%d]esaddr_offset:0x%lx\n", __func__, __LINE__, esaddr_offset); - VLOG(INFO,"[%s][%d]espVirAddr:0x%lx\n", __func__, __LINE__, espVirAddr); - VLOG(INFO,"[%s][%d]eslength:%d\n", __func__, __LINE__, eslength); - - length_cp = ((eslength + 15) >> 4) << 4; - memcpy(buffer, (const void *)((ulong)espVirAddr), length_cp); - *buf_nal_size = eslength; - (*frame_type) = handle->enc_es.frame_type; - VLOG(INFO,"[%s][%d]buf_nal_size:%d,frame_type:%d\n", __func__, __LINE__,*buf_nal_size,(*frame_type)); + if (handle->v4l2_enable) { + venc_info_t *venc = &s_venc_info; + struct v4l2_buffer dst_buf; + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + int ret = -1; + + ret = dequeue_buffer_mplane(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &dst_buf, planes, 0); + while (ret != 0) { + usleep(1000); + ret = dequeue_buffer_mplane(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &dst_buf, planes, 0); + } + + if (ret == 0) { + handle->data_len = 0; + if (dst_buf.length > 0 && dst_buf.m.planes) { + for (int p = 0; p < dst_buf.length; p++) { + handle->data_len += dst_buf.m.planes[p].bytesused; + } + } + + safe_memcpy(buffer, dst_buffers[dst_buf.index], handle->data_len); + if (dst_buf.flags & V4L2_BUF_FLAG_LAST) { + printf("End of stream reached\n"); + } + + if (dst_buf.flags & V4L2_BUF_FLAG_KEYFRAME) { + (*frame_type) = 0; + } + else { + (*frame_type) = 1; + } + + if (queue_buffer_mplane(venc->venc_fd, &dst_buf) < 0) { + printf("queue_buffer_mplane err\n"); + } + + (*buf_nal_size) = handle->data_len; + + } else if (ret != -EAGAIN) { + perror("dequeue dst failed"); + } + } + else { + venc_info_t *venc = &s_venc_info; + unsigned int esaddr_offset = 0; + unsigned long esPhyAddr; + int eslength; + unsigned long espVirAddr = 0; + unsigned long slice_header_length = 0; + int length_cp = 0; + + slice_header_length = handle->enc_es.slice_header_length; + esPhyAddr = handle->enc_es.esPhyAddr; + eslength = handle->enc_es.eslength; + esaddr_offset = esPhyAddr - venc->common_buffer[handle->chn_id].phys_addr; + espVirAddr = venc->common_buffer[handle->chn_id].virt_addr + esaddr_offset; + VLOG(INFO,"[%s][%d]offset:0x%x\n", __func__, __LINE__, slice_header_length); + VLOG(INFO,"[%s][%d]esPhyAddr:0x%lx\n", __func__, __LINE__, esPhyAddr); + VLOG(INFO,"[%s][%d]esaddr_offset:0x%lx\n", __func__, __LINE__, esaddr_offset); + VLOG(INFO,"[%s][%d]espVirAddr:0x%lx\n", __func__, __LINE__, espVirAddr); + VLOG(INFO,"[%s][%d]eslength:%d\n", __func__, __LINE__, eslength); + + length_cp = ((eslength + 15) >> 4) << 4; + memcpy(buffer, (const void *)((ulong)espVirAddr), length_cp); + *buf_nal_size = eslength; + (*frame_type) = handle->enc_es.frame_type; + VLOG(INFO,"[%s][%d]buf_nal_size:%d,frame_type:%d\n", __func__, __LINE__,*buf_nal_size,(*frame_type)); + } return 0; } @@ -191,10 +597,43 @@ int check_initparam(handle_t handle) void encoder_open(char *fwfile) { - venc_init(); - vrisc_reset(); - firmware_load(fwfile); - firmware_boot(); +// venc_init(); +// vrisc_reset(); +// firmware_load(fwfile); +// firmware_boot(); + + venc_info_t *venc = &s_venc_info; + struct v4l2_capability cap; + + + memset(&s_venc_info, 0x00, sizeof(s_venc_info)); + s_venc_info.venc_fd = -1; + + venc->venc_fd = open("/dev/video90", O_RDWR); + if (venc->venc_fd < 0) { + VLOG(INFO,"[VENC] Can't open venc driver. [error=%s]. \n", strerror(errno)); +// return -1; + } + VLOG(INFO,"open venc fd:%d,&venc:%lx!",venc->venc_fd,(unsigned long)venc); + + if (ioctl(venc->venc_fd, VIDIOC_QUERYCAP, &cap) < 0) { + perror("VIDIOC_QUERYCAP failed"); + close(venc->venc_fd); +// return -1; + } + printf("Driver: %s\n", cap.driver); + printf("Card: %s\n", cap.card); + printf("Bus: %s\n", cap.bus_info); + printf("Capabilities: 0x%08x\n", cap.capabilities); + + if (!(cap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE)) { + printf("Device does not support V4L2_CAP_VIDEO_M2M_MPLANE\n"); + printf("Try using non-mplane version\n"); + close(venc->venc_fd); +// return -1; + } + printf("Device supports M2M MPLANE\n"); + } void encoder_unmap(int inst_id) { @@ -213,41 +652,58 @@ void encoder_close() { int vl_tahoe_encoder_init(int codec_id, handle_t encode_info) { // int ret; -// VPMultiEncHandle* mHandle = (VPMultiEncHandle *) malloc(sizeof(VPMultiEncHandle)); -// -// if (mHandle == NULL) -// goto exit; -// memset(mHandle, 0, sizeof(VPMultiEncHandle)); -// if (!check_qp_tbl(qp_tbl)) { -// goto exit; -// } -// -// vp5_set_log_level(ERR); -// -// ret = initEncParams(mHandle, codec_id, encode_info, qp_tbl); -// if (ret < 0) -// goto exit; -// -// mHandle->am_enc_handle = AML_MultiEncInitialize(&(mHandle->mEncParams)); -// if (mHandle->am_enc_handle == 0) -// goto exit; -// mHandle->mPrependSPSPPSToIDRFrames = -// encode_info.prepend_spspps_to_idr_frames; -// mHandle->mSpsPpsHeaderReceived = false; -// mHandle->mNumInputFrames = -1; // 1st two buffers contain SPS and PPS -// if (encode_info.strict_rc_window > MAX_FRAME_WINDOW) -// encode_info.strict_rc_window = MAX_FRAME_WINDOW; -// mHandle->hist_win_len = encode_info.strict_rc_window; -// mHandle->hist_skip_thresh = encode_info.strict_rc_skip_thresh; + venc_info_t *venc = &s_venc_info; + if (check_initparam(encode_info)) { printf("check_initparam failed\n"); return -1; } - vdi_alloc_common_buffer(encode_info.chn_id); - venc_lock(); - create_channel(encode_info); - venc_unlock(); +// vdi_alloc_common_buffer(encode_info.chn_id); +// venc_lock(); +// create_channel(encode_info); +// venc_unlock(); + + setup_encoder_params(venc->venc_fd, &encode_info); + if (setup_src_format_mplane(venc->venc_fd, &encode_info, 1) < 0) { + close(venc->venc_fd); + return -1; + } + + if (setup_dst_format_mplane(venc->venc_fd, &encode_info) < 0) { + close(venc->venc_fd); + return -1; + } + + if (setup_buffers_mplane(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 2, + &src_buf_info, &src_buffers, &src_buf_lengths, &src_buf_count, 0) < 0) { + close(venc->venc_fd); + return -1; + } + + if (setup_buffers_mplane(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 2, + &dst_buf_info, &dst_buffers, &dst_buf_lengths, &dst_buf_count, 0) < 0) { + close(venc->venc_fd); + return -1; + } + + for (int i = 0; i < dst_buf_count; i++) { + if (queue_buffer_mplane(venc->venc_fd, &dst_buf_info[i]) < 0) { + close(venc->venc_fd); + return -1; + } + } + + if (stream_on(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { + close(venc->venc_fd); + return -1; + } + if (stream_on(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) { + close(venc->venc_fd); + return -1; + } + printf("Stream started\n"); + return 0; // return (vl_codec_handle_t)mHandle; @@ -258,6 +714,75 @@ int vl_tahoe_encoder_init(int codec_id, handle_t encode_info) { // return (vl_codec_handle_t)NULL; } + +int vl_v4l2_switch_to_dmamode( handle_t encode_info,int plane_num) { + venc_info_t *venc = &s_venc_info; + + VLOG(ERR,"switch to dmamode!\n"); + + stream_off(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + stream_off(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + + for (int i = 0; i < src_buf_count; i++) { + munmap(src_buffers[i], src_buf_lengths[i]); + } + for (int i = 0; i < dst_buf_count; i++) { + munmap(dst_buffers[i], dst_buf_lengths[i]); + } + + free(src_buffers); + free(dst_buffers); + for (int i = 0; i < src_buf_count; i++) { + free(src_buf_info[i].m.planes); + } + free(src_buf_info); + free(dst_buf_info); + free(src_buf_lengths); + free(dst_buf_lengths); + + setup_encoder_params(venc->venc_fd, &encode_info); + if (setup_src_format_mplane(venc->venc_fd, &encode_info, plane_num) < 0) { + close(venc->venc_fd); + return -1; + } + + if (setup_dst_format_mplane(venc->venc_fd, &encode_info) < 0) { + close(venc->venc_fd); + return -1; + } + + if (setup_buffers_mplane(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 2, + &src_buf_info, &src_buffers, &src_buf_lengths, &src_buf_count, V4L2_MEMORY_DMABUF) < 0) { + close(venc->venc_fd); + return -1; + } + + if (setup_buffers_mplane(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 2, + &dst_buf_info, &dst_buffers, &dst_buf_lengths, &dst_buf_count, 0) < 0) { + close(venc->venc_fd); + return -1; + } + + for (int i = 0; i < dst_buf_count; i++) { + if (queue_buffer_mplane(venc->venc_fd, &dst_buf_info[i]) < 0) { + close(venc->venc_fd); + return -1; + } + } + + if (stream_on(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { + close(venc->venc_fd); + return -1; + } + if (stream_on(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) { + close(venc->venc_fd); + return -1; + } + printf("Stream started\n"); +} + + + int vl_video_encoder_change_bitrate(handle_t *encode_info, int bitRate) { @@ -387,33 +912,85 @@ static int encode_poll(int fd, int timeout) { return poll(poll_fd, 1, timeout); } -int vl_tahoe_encoder_encode(handle_t *encode_info) +int num = 0; +bool get_input_buf_forv4l(ulong *pInput,struct v4l2_buffer *src_buf,handle_t *encode_info) { + venc_info_t *venc = &s_venc_info; + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + int ret = -1; + enum v4l2_memory type; + + if (encode_info->current_mode == 3) { + type = V4L2_MEMORY_DMABUF; + } + else { + type = V4L2_MEMORY_MMAP; + } + + if (num < 2) { + memcpy(src_buf,&src_buf_info[num],sizeof(struct v4l2_buffer)); + //src_buf = &src_buf_info[num]; + ret = 0; + num++; + } else { + ret = dequeue_buffer_mplane(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, src_buf, planes, type); + while (ret != 0) { + usleep(1000); + ret = dequeue_buffer_mplane(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, src_buf, planes, type); + } + } + if (ret == 0) { + (*pInput) = src_buffers[src_buf->index]; + return true; + } + return false; +} + + + +int vl_tahoe_encoder_encode(handle_t *encode_info,struct v4l2_buffer *src_buf) { - int ret = 0; +// int ret = 0; //vdi_debug(encode_info->chn_id); - venc_lock(); - roi_config(encode_info); - osd_config(encode_info); - if (encode_info->cfg_update == 1) { - dynamic_parameter_set(encode_info); - encode_info->cfg_update = 0; - } - encode_one_frame(encode_info); - if (encode_poll(s_venc_info.venc_fd, -1) <= 0) { - VLOG(ERR,"[%s][%d]poll fail\n", __func__, __LINE__); - return -1; +// venc_lock(); +// roi_config(encode_info); +// osd_config(encode_info); +// if (encode_info->cfg_update == 1) { +// dynamic_parameter_set(encode_info); +// encode_info->cfg_update = 0; +// } +// encode_one_frame(encode_info); +// if (encode_poll(s_venc_info.venc_fd, -1) <= 0) { +// VLOG(ERR,"[%s][%d]poll fail\n", __func__, __LINE__); +// return -1; +// } +// encode_info->enc_es.slice_header_length = venc_read_register(TAHOE_EC_DMA0) & 0x3F; +// encode_info->enc_es.esPhyAddr = venc_read_register(TAHOE_EC_DMA0) - encode_info->enc_es.slice_header_length; +// encode_info->enc_es.esPhyAddr |= (((ulong)(venc_read_register(TAHOE_EC_DMA6) & 0x03)) << 32); +// encode_info->enc_es.eslength = venc_read_register(TAHOE_EC_LENGTH); +// encode_info->enc_es.frame_type = venc_read_register(OUTPUT_FRAME_TYPE); +// +// VLOG(INFO,"es buffer phyaddr:%lx,lsb:%x",encode_info->enc_es.esPhyAddr,(venc_read_register(TAHOE_EC_DMA0) - encode_info->enc_es.slice_header_length)); +// +// venc_unlock(); + venc_info_t *venc = &s_venc_info; + struct v4l2_buffer dst_buf; + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + int ret = 0;//-1; + + if (encode_info->current_mode == VMALLOC_TYPE) { + if (src_buf && (src_buf->length > 0) && src_buf->m.planes) { + int y_size = encode_info->enc_width * encode_info->enc_height; + int uv_size = (encode_info->enc_width / 2) * (encode_info->enc_height / 2) * 2; + src_buf->m.planes[0].bytesused = y_size + uv_size;//一个planes的情况 + } } - encode_info->enc_es.slice_header_length = venc_read_register(TAHOE_EC_DMA0) & 0x3F; - encode_info->enc_es.esPhyAddr = venc_read_register(TAHOE_EC_DMA0) - encode_info->enc_es.slice_header_length; - encode_info->enc_es.esPhyAddr |= (((ulong)(venc_read_register(TAHOE_EC_DMA6) & 0x03)) << 32); - encode_info->enc_es.eslength = venc_read_register(TAHOE_EC_LENGTH); - encode_info->enc_es.frame_type = venc_read_register(OUTPUT_FRAME_TYPE); - VLOG(INFO,"es buffer phyaddr:%lx,lsb:%x",encode_info->enc_es.esPhyAddr,(venc_read_register(TAHOE_EC_DMA0) - encode_info->enc_es.slice_header_length)); + if (queue_buffer_mplane(venc->venc_fd, src_buf) < 0) { + printf("queue_buffer_mplane err\n"); + } - venc_unlock(); return ret; } @@ -428,9 +1005,31 @@ int vl_tahoe_encoder_destroy(handle_t encode_info) { // free(handle->mSPSPPSData); // if (handle) // free(handle); - venc_lock(); - destroy_channel(encode_info); - venc_unlock(); +// venc_lock(); +// destroy_channel(encode_info); +// venc_unlock(); + + venc_info_t *venc = &s_venc_info; + stream_off(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + stream_off(venc->venc_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + + for (int i = 0; i < src_buf_count; i++) { + munmap(src_buffers[i], src_buf_lengths[i]); + } + for (int i = 0; i < dst_buf_count; i++) { + munmap(dst_buffers[i], dst_buf_lengths[i]); + } + free(src_buffers); + free(dst_buffers); + for (int i = 0; i < src_buf_count; i++) { + free(src_buf_info[i].m.planes); + } + free(src_buf_info); + free(dst_buf_info); + free(src_buf_lengths); + free(dst_buf_lengths); + + close(venc->venc_fd); return 1; } diff --git a/amvenc_tahoe/tahoe_enc/libvptahoe_codec.h b/amvenc_tahoe/tahoe_enc/libvptahoe_codec.h index 791c3d7..b81f1f5 100644 --- a/amvenc_tahoe/tahoe_enc/libvptahoe_codec.h +++ b/amvenc_tahoe/tahoe_enc/libvptahoe_codec.h @@ -34,6 +34,7 @@ #define _VP_CODEC_TAHOE_H_ #include "vp_codec_tahoe.h" +#include void encoder_open(char *fwfile); void encoder_close(); @@ -47,11 +48,14 @@ int vl_video_encoder_change_qp(handle_t *encode_info, int minQpI, int maxQpI, int maxDeltaQp, int minQpP, int maxQpP, int minQpB, int maxQpB); -int vl_tahoe_encoder_encode(handle_t *encode_info); +int vl_tahoe_encoder_encode(handle_t *encode_info,struct v4l2_buffer *src_buf); int get_dsframe(handle_t *handle, unsigned char *buffer, unsigned int *buf_nal_size); int get_bsbframe(handle_t *handle, unsigned char *buffer, unsigned int *buf_nal_size, signed char *frame_type); int get_header(handle_t *handle, unsigned char *pHeader, unsigned int *pLength); int check_initparam(handle_t handle); int vl_tahoe_encoder_generate_header(handle_t *encode_info); +bool get_input_buf_forv4l(ulong *pInput,struct v4l2_buffer *src_buf, handle_t *encode_info); +void detectV4l2Support(handle_t *encode_info); +int vl_v4l2_switch_to_dmamode( handle_t encode_info,int plane_num) ; #endif diff --git a/amvenc_tahoe/tahoe_enc/libvptahoe_wrapper.c b/amvenc_tahoe/tahoe_enc/libvptahoe_wrapper.c index 37f9e51..9303bea 100644 --- a/amvenc_tahoe/tahoe_enc/libvptahoe_wrapper.c +++ b/amvenc_tahoe/tahoe_enc/libvptahoe_wrapper.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include #define FW_STRING_LEN_MAX 256 #define HE_BUF_SIZE 0x100000 @@ -62,7 +64,6 @@ int output_fd_dump = -1; #endif - vl_codec_tahoe_handle_t vt_tahoe_encoder_init(int codec_id, vt_encode_info_t encode_param) { venc_buffer_t hdBuffer[3] = {0}; char fwfile[FW_STRING_LEN_MAX] = {0}; @@ -130,6 +131,8 @@ vl_codec_tahoe_handle_t vt_tahoe_encoder_init(int codec_id, vt_encode_info_t enc }*/ snprintf(fwfile, FW_STRING_LEN_MAX, "%s", FW_PATH); + detectV4l2Support(encode_info); + if (0 == get_cur_instance()) { VLOG(INFO,"loading fw:%s\n",fwfile); encoder_open(fwfile); @@ -158,22 +161,25 @@ vl_codec_tahoe_handle_t vt_tahoe_encoder_init(int codec_id, vt_encode_info_t enc encode_info->input_buf[0].size = encode_info->enc_width * encode_info->enc_height * 4;//fix me!!! } - if (vdi_allocate_dma_memory(&encode_info->input_buf[0]) < 0) { - VLOG(ERR,"Can not allocat input Buffer in vmalloc mode!\n"); - return -1; - } - - for (i = 0; i < 3; i++) { - memset(&hdBuffer[i], 0, sizeof(hdBuffer[i])); - hdBuffer[i].size = HE_BUF_SIZE; - if (vdi_allocate_dma_memory(&hdBuffer[i]) < 0) { - printf("Can not allocat hd Buffer chnid %d\n", encode_info->chn_id); + if (!encode_info->v4l2_enable) { + if (vdi_allocate_dma_memory(&encode_info->input_buf[0]) < 0) { + VLOG(ERR,"Can not allocat input Buffer in vmalloc mode!\n"); return -1; } - VLOG(INFO,"[%s][%d]hdBuffer[%d].phys_addr:0x%x\n", \ - __func__,__LINE__, i, hdBuffer[i].phys_addr); - encode_info->header_buf_addr[i] = hdBuffer[i].phys_addr; + + for (i = 0; i < 3; i++) { + memset(&hdBuffer[i], 0, sizeof(hdBuffer[i])); + hdBuffer[i].size = HE_BUF_SIZE; + if (vdi_allocate_dma_memory(&hdBuffer[i]) < 0) { + printf("Can not allocat hd Buffer chnid %d\n", encode_info->chn_id); + return -1; + } + VLOG(INFO,"[%s][%d]hdBuffer[%d].phys_addr:0x%x\n", \ + __func__,__LINE__, i, hdBuffer[i].phys_addr); + encode_info->header_buf_addr[i] = hdBuffer[i].phys_addr; + } } + #if DUMP_FILE_ENABLE input_fd_dump = open("/data/tahoe_dump_input.yuv", O_CREAT | O_RDWR | O_TRUNC, 0644); if (input_fd_dump < 0) @@ -288,6 +294,7 @@ vt_encoding_metadata_t vt_tahoe_encoder_encode(vl_codec_tahoe_handle_t codec_han //venc_buffer_t input_buf = {0}; int header_length = 0; int i = 0; + struct v4l2_buffer src_buf; tahoe_dma_buf_info_t dma_info_map; memset(&result,0,sizeof(result)); @@ -300,6 +307,12 @@ vt_encoding_metadata_t vt_tahoe_encoder_encode(vl_codec_tahoe_handle_t codec_han } if (VMALLOC_TYPE == in_buffer_info->buf_type) { + encode_info->current_mode = VMALLOC_TYPE; + if (encode_info->v4l2_enable) { + if (!get_input_buf_forv4l(&encode_info->input_buf[0].virt_addr,&src_buf,encode_info)) { + VLOG(ERR,"get_input_buf_forv4l failed\n"); + } + } if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_NV12 || encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_NV21 || encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_YUV420_PLANAR) { //need fix @@ -323,11 +336,21 @@ vt_encoding_metadata_t vt_tahoe_encoder_encode(vl_codec_tahoe_handle_t codec_han encode_info->buf_stride = encode_info->enc_width; //fix me!!! VLOG(INFO,"vmalloc mode,input data addr:%x %x %x\n",encode_info->tahoe_enc_pic.inpt_buf_addr[0],encode_info->tahoe_enc_pic.inpt_buf_addr[1],encode_info->tahoe_enc_pic.inpt_buf_addr[2]); } - #if 1 else if (DMA_TYPE == in_buffer_info->buf_type) { - vt_dma_info_t *dma_info; - dma_info = &(in_buffer_info->buf_info.dma_info); + vt_dma_info_t *dma_info; + dma_info = &(in_buffer_info->buf_info.dma_info); + + if (encode_info->v4l2_enable && (DMA_TYPE != encode_info->current_mode)) { + encode_info->current_mode = DMA_TYPE; + vl_v4l2_switch_to_dmamode(*encode_info,dma_info->num_planes); + } + if (encode_info->v4l2_enable) { + if (!get_input_buf_forv4l(&encode_info->input_buf[0].virt_addr,&src_buf,encode_info)) { + VLOG(ERR,"get_input_buf_forv4l failed\n"); + } + } + if (encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_NV12 || encode_info->mfdin_input_fmt == MFDI_INPUT_FMT_NV21) { if (dma_info->num_planes != 1 && dma_info->num_planes != 2) { VLOG(ERR,"invalid num_planes %d\n", dma_info->num_planes); @@ -371,7 +394,10 @@ vt_encoding_metadata_t vt_tahoe_encoder_encode(vl_codec_tahoe_handle_t codec_han dma_info_map.fd[i] = dma_info->shared_fd[i]; VLOG(INFO,"instance %d:**shared_fd %d\n", encode_info->chn_id,dma_info->shared_fd[i]); } - vdi_config_dma(&dma_info_map); + + if (!encode_info->v4l2_enable) { + vdi_config_dma(&dma_info_map); + } VLOG(INFO,"instance %d:dma map num_planes:%d\n",encode_info->chn_id,dma_info_map.num_planes); encode_info->buf_stride = ((encode_info->enc_width + 15) >> 4) << 4; @@ -385,15 +411,51 @@ vt_encoding_metadata_t vt_tahoe_encoder_encode(vl_codec_tahoe_handle_t codec_han encode_info->tahoe_enc_pic.inpt_buf_addr[2] = encode_info->tahoe_enc_pic.inpt_buf_addr[1] + encode_info->buf_stride * encode_info->enc_height / 4; } + + if (encode_info->v4l2_enable) { + src_buf.m.planes[0].bytesused = encode_info->buf_stride * encode_info->enc_height * 3 / 2; + src_buf.m.planes[0].length = encode_info->buf_stride * encode_info->enc_height * 3 / 2; + src_buf.m.planes[0].m.fd = dma_info->shared_fd[0]; + } } } - if (dma_info_map.num_planes > 1 ) + if (dma_info_map.num_planes > 1 ) encode_info->tahoe_enc_pic.inpt_buf_addr[1]= dma_info_map.phys_addr[1]; if (dma_info_map.num_planes > 2) encode_info->tahoe_enc_pic.inpt_buf_addr[2]= dma_info_map.phys_addr[2]; + + if (encode_info->v4l2_enable && (dma_info_map.num_planes == 2)) { + src_buf.m.planes[0].bytesused = encode_info->buf_stride * encode_info->enc_height; + src_buf.m.planes[0].length = encode_info->buf_stride * encode_info->enc_height; + src_buf.m.planes[0].m.fd = dma_info->shared_fd[0]; + + src_buf.m.planes[1].bytesused = encode_info->buf_stride * encode_info->enc_height / 2; + src_buf.m.planes[1].m.fd = dma_info->shared_fd[1]; + src_buf.m.planes[1].length = encode_info->buf_stride * encode_info->enc_height / 2; + } + + if (encode_info->v4l2_enable && (dma_info_map.num_planes == 3)) { + src_buf.m.planes[0].bytesused = encode_info->buf_stride * encode_info->enc_height; + src_buf.m.planes[0].length = encode_info->buf_stride * encode_info->enc_height; + src_buf.m.planes[0].m.fd = dma_info->shared_fd[0]; + + src_buf.m.planes[1].bytesused = encode_info->buf_stride * encode_info->enc_height / 4; + src_buf.m.planes[1].length = encode_info->buf_stride * encode_info->enc_height / 4; + src_buf.m.planes[1].m.fd = dma_info->shared_fd[1]; + + src_buf.m.planes[2].bytesused = encode_info->buf_stride * encode_info->enc_height / 4; + src_buf.m.planes[2].length = encode_info->buf_stride * encode_info->enc_height / 4; + src_buf.m.planes[2].m.fd = dma_info->shared_fd[2]; + } } -#endif - ret = vl_tahoe_encoder_encode(encode_info); + + if (encode_info->v4l2_enable) { + ret = vl_tahoe_encoder_encode(encode_info,&src_buf); + } + else { + ret = vl_tahoe_encoder_encode(encode_info, 0); + } + if (ret < 0) { VLOG(ERR,"send encode cmd to encoder failed!ret:%d \n",ret); result.is_valid = 0; @@ -403,7 +465,9 @@ vt_encoding_metadata_t vt_tahoe_encoder_encode(vl_codec_tahoe_handle_t codec_han if (0 == encode_info->enc_es.frame_type || 1 == encode_info->enc_es.frame_type) { VLOG(INFO,"IDR or I frame!!\n"); - vt_tahoe_encoder_generate_header(codec_handle, out, &header_length); + if (!encode_info->v4l2_enable) { + vt_tahoe_encoder_generate_header(codec_handle, out, &header_length); + } result.is_key_frame = 1; } @@ -426,7 +490,7 @@ vt_encoding_metadata_t vt_tahoe_encoder_encode(vl_codec_tahoe_handle_t codec_han VLOG(INFO,"dump tahoe output file,%d",result.encoded_data_length_in_bytes); } #endif - if (DMA_TYPE == in_buffer_info->buf_type) { + if ((DMA_TYPE == in_buffer_info->buf_type) && (!encode_info->v4l2_enable)) { ret = vdi_unmap_dma(&dma_info_map); if (ret != 0) { VLOG(ERR,"vdi_unmap_dma src buffer failed!!\n"); diff --git a/amvenc_tahoe/tahoe_enc/tahoe.h b/amvenc_tahoe/tahoe_enc/tahoe.h index 7485890..019fa67 100644 --- a/amvenc_tahoe/tahoe_enc/tahoe.h +++ b/amvenc_tahoe/tahoe_enc/tahoe.h @@ -270,6 +270,11 @@ typedef struct { u8 golden_match_flag; venc_buffer_t input_buf[3]; u8 svc_enable; + unsigned char *out; + unsigned char *input_yuvbuf; + int data_len; + unsigned char v4l2_enable; + unsigned char current_mode; } handle_t; #define TAHOE_REG_BASE_ADDR 0xFE370000 diff --git a/amvenc_tahoe/test.c b/amvenc_tahoe/test.c index a84455f..9a5bac0 100644 --- a/amvenc_tahoe/test.c +++ b/amvenc_tahoe/test.c @@ -504,6 +504,7 @@ static void *encode_thread(void *param) int frame_num; int End_status = 0; int pw = 0; + struct v4l2_buffer src_buf; if (NULL != param) cfg_encode = (encodecCfgParam *)param; @@ -634,6 +635,7 @@ static void *encode_thread(void *param) End_status = -1; goto exit; } + printf("open success,fd:%d\n",fp); if (cfg_encode->cfg_upd_enabled) { fp_cfg = fopen((const char*)cfg_encode->cfg_file, "r"); @@ -709,6 +711,9 @@ static void *encode_thread(void *param) } memset(&encode_info, 0, sizeof(handle_t)); + + detectV4l2Support(&encode_info); + encode_info.init_qp = 30; encode_info.enc_rc_mode = 2; encode_info.chn_id = cfg_encode->chnid; @@ -965,29 +970,31 @@ static void *encode_thread(void *param) } } } else { - memset(&pFbSrcMem, 0, sizeof(pFbSrcMem)); - pFbSrcMem.size = framesize; - pFbSrcMem.cached = 1; + if (!encode_info.v4l2_enable) { + memset(&pFbSrcMem, 0, sizeof(pFbSrcMem)); + pFbSrcMem.size = framesize; + pFbSrcMem.cached = 1; - if (vdi_allocate_dma_memory(&pFbSrcMem) < 0) { - printf("Can not allocat dma Buffer chnid %d\n", encode_info.chn_id); - End_status = -1; - goto end; + if (vdi_allocate_dma_memory(&pFbSrcMem) < 0) { + printf("Can not allocat dma Buffer chnid %d\n", encode_info.chn_id); + End_status = -1; + goto end; + } } } //for vps/sps/pps - for (i = 0; i < 3; i++) { - memset(&bsBuffer[i], 0, sizeof(bsBuffer[i])); - bsBuffer[i].size = ENC_STREAM_BUF_SIZE; - if (vdi_allocate_dma_memory(&bsBuffer[i]) < 0) { - printf("Can not allocat dma Buffer chnid %d\n", encode_info.chn_id); - End_status = -1; - goto end; - } - printf("[%s][%d]bsBuffer[%d].phys_addr:0x%x\n", \ - __func__,__LINE__, i, bsBuffer[i].phys_addr); - } +// for (i = 0; i < 3; i++) { +// memset(&bsBuffer[i], 0, sizeof(bsBuffer[i])); +// bsBuffer[i].size = ENC_STREAM_BUF_SIZE; +// if (vdi_allocate_dma_memory(&bsBuffer[i]) < 0) { +// printf("Can not allocat dma Buffer chnid %d\n", encode_info.chn_id); +// End_status = -1; +// goto end; +// } +// printf("[%s][%d]bsBuffer[%d].phys_addr:0x%x\n", \ +// __func__,__LINE__, i, bsBuffer[i].phys_addr); +// } if (!encode_info.buf_stride) { @@ -1013,28 +1020,42 @@ static void *encode_thread(void *param) printf("header buf addr:%lx %lx %lx\n",encode_info.header_buf_addr[0],encode_info.header_buf_addr[1],encode_info.header_buf_addr[2]); printf("New allocate frame address y:0x%x cb:0x%x cr:0x%x\n", encode_info.tahoe_enc_pic.inpt_buf_addr[0], encode_info.tahoe_enc_pic.inpt_buf_addr[1], encode_info.tahoe_enc_pic.inpt_buf_addr[2]); +#if 0 + encode_info.out = (unsigned char *) malloc(outbuffer_len); + if (encode_info.out == NULL) { + printf("Can not malloc outbuffer\n"); + End_status = -1; + goto end; + } + encode_info.input_yuvbuf = (unsigned char *) malloc(framesize); + if (encode_info.input_yuvbuf == NULL) { + printf("Can not allocat inputBuffer\n"); + End_status = -1; + goto exit; + } +#endif if (vl_tahoe_encoder_init(encode_info.enc_fmt, encode_info) < 0) { printf("vl_tahoe_encoder_init failed chnid %d\n", encode_info.chn_id); End_status = -1; goto exit; } - if (cfg_encode->power_test_enabled) { - for (pw = 0; pw < POWER_TEST_NUM_MAX; pw++) { - if (fread(inputBuffer, 1, framesize, fp) != framesize) - { - rewind(fp); - clearerr(fp); - if (fread(inputBuffer, 1, framesize, fp) != framesize) { - printf("read input file error!\n"); - End_status = -1; - goto exit; - } - } - memcpy((void *)((unsigned long)pFbPwSrcMem[pw].virt_addr), inputBuffer, framesize); - } - } +// if (cfg_encode->power_test_enabled) { +// for (pw = 0; pw < POWER_TEST_NUM_MAX; pw++) { +// if (fread(inputBuffer, 1, framesize, fp) != framesize) +// { +// rewind(fp); +// clearerr(fp); +// if (fread(inputBuffer, 1, framesize, fp) != framesize) { +// printf("read input file error!\n"); +// End_status = -1; +// goto exit; +// } +// } +// memcpy((void *)((unsigned long)pFbPwSrcMem[pw].virt_addr), inputBuffer, framesize); +// } +// } gettimeofday(&timeStart, NULL); for (i = 0; i < cfg_encode->num; i++) { @@ -1051,6 +1072,12 @@ static void *encode_thread(void *param) encode_info.tahoe_enc_pic.inpt_buf_addr[2] = pFbPwSrcMem[pw].phys_addr + (encode_info.buf_stride * encode_info.enc_height * 5 / 4); } } else { + if (encode_info.v4l2_enable) { + if (!get_input_buf_forv4l(&pFbSrcMem.virt_addr,&src_buf,&encode_info)) { + VLOG(ERR,"get_input_buf_forv4l failed\n"); + } + } + if (fread(inputBuffer, 1, framesize, fp) != framesize) { rewind(fp); @@ -1062,6 +1089,7 @@ static void *encode_thread(void *param) } } memcpy((void *)((unsigned long)pFbSrcMem.virt_addr), inputBuffer, framesize); + } if (cfg_encode->osd_enabled) { @@ -1090,27 +1118,34 @@ static void *encode_thread(void *param) encode_info.poc = 0; if (encode_info.enc_frame_type == FRAME_TYPE_IDR || encode_info.enc_frame_type == FRAME_TYPE_I) { - vl_tahoe_encoder_generate_header(&encode_info); - ret = get_header(&encode_info, outbuffer, (unsigned int *)&dataLength); - if (ret == 0) { - write(outfd, (unsigned char *) outbuffer, dataLength); + if (!encode_info.v4l2_enable) { + vl_tahoe_encoder_generate_header(&encode_info); + ret = get_header(&encode_info, outbuffer, (unsigned int *)&dataLength); + if (ret == 0) { + write(outfd, (unsigned char *) outbuffer, dataLength); + } } } - vl_tahoe_encoder_encode(&encode_info); + if (encode_info.v4l2_enable) { + vl_tahoe_encoder_encode(&encode_info,&src_buf); + } + else { + vl_tahoe_encoder_encode(&encode_info,0); + } + ret = get_bsbframe(&encode_info, outbuffer, (unsigned int *)&dataLength, &frame_type); gettimeofday(&writeStart, NULL); if (ret == 0) { - write(outfd, (unsigned char *) outbuffer, - dataLength); - } - if (cfg_encode->ds_enabled) { - ret = get_dsframe(&encode_info, outbuffer, (unsigned int *)&dataLength); - if (ret == 0) { - write(dsfd, (unsigned char *) outbuffer, - dataLength); - } + write(outfd, outbuffer, dataLength); } +// if (cfg_encode->ds_enabled) { +// ret = get_dsframe(&encode_info, outbuffer, (unsigned int *)&dataLength); +// if (ret == 0) { +// write(dsfd, (unsigned char *) outbuffer, +// dataLength); +// } +// } gettimeofday(&writeEnd, NULL); frameWriteTime = uTimeDiff(writeEnd, writeStart); ioTime += frameWriteTime; -- 2.43.2