3195 lines
113 KiB
C
3195 lines
113 KiB
C
![]() |
/*
|
||
|
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <sys/ioctl.h>
|
||
|
#include <sys/poll.h>
|
||
|
#include <sys/time.h>
|
||
|
#include <sys/select.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <errno.h>
|
||
|
#include <pthread.h>
|
||
|
#include <math.h>
|
||
|
#include <unistd.h>
|
||
|
#include <signal.h>
|
||
|
#include <sys/prctl.h>
|
||
|
#include <limits.h>
|
||
|
|
||
|
#include "sample_comm.h"
|
||
|
#include "heif_format.h"
|
||
|
|
||
|
#define TEMP_BUF_LEN 8
|
||
|
#define MAX_THM_SIZE (64 * 1024)
|
||
|
#define QPMAP_BUF_NUM 8
|
||
|
#define VENC_QPMAP_MAX_CHN 2
|
||
|
|
||
|
#define SAMPLE_RETURN_CONTINUE 1
|
||
|
#define SAMPLE_RETURN_BREAK 2
|
||
|
#define SAMPLE_RETURN_NULL 3
|
||
|
#define SAMPLE_RETURN_GOTO 4
|
||
|
#define SAMPLE_RETURN_FAILURE (-1)
|
||
|
|
||
|
typedef struct {
|
||
|
td_u32 qpmap_size[VENC_QPMAP_MAX_CHN];
|
||
|
td_phys_addr_t qpmap_phys_addr[VENC_QPMAP_MAX_CHN][QPMAP_BUF_NUM];
|
||
|
td_void *qpmap_vir_addr[VENC_QPMAP_MAX_CHN][QPMAP_BUF_NUM];
|
||
|
|
||
|
td_u32 skip_weight_size[VENC_QPMAP_MAX_CHN];
|
||
|
td_phys_addr_t skip_weight_phys_addr[VENC_QPMAP_MAX_CHN][QPMAP_BUF_NUM];
|
||
|
td_void *skip_weight_vir_addr[VENC_QPMAP_MAX_CHN][QPMAP_BUF_NUM];
|
||
|
} sample_comm_venc_frame_proc_info;
|
||
|
|
||
|
typedef struct {
|
||
|
FILE *file[OT_VENC_MAX_CHN_NUM];
|
||
|
td_s32 venc_fd[OT_VENC_MAX_CHN_NUM];
|
||
|
td_s32 maxfd;
|
||
|
td_u32 picture_cnt[OT_VENC_MAX_CHN_NUM];
|
||
|
td_char file_name[OT_VENC_MAX_CHN_NUM][FILE_NAME_LEN];
|
||
|
td_char real_file_name[OT_VENC_MAX_CHN_NUM][PATH_MAX];
|
||
|
ot_venc_chn venc_chn;
|
||
|
td_char file_postfix[10]; /* 10 :file_postfix number */
|
||
|
td_s32 chn_total;
|
||
|
td_bool save_heif;
|
||
|
} sample_comm_venc_stream_proc_info;
|
||
|
|
||
|
const td_u8 g_soi[2] = { 0xFF, 0xD8 }; /* 2 is a number */
|
||
|
const td_u8 g_eoi[2] = { 0xFF, 0xD9 }; /* 2 is a number */
|
||
|
|
||
|
static pthread_t g_venc_pid;
|
||
|
static pthread_t g_venc_qpmap_pid;
|
||
|
static struct_venc_getstream_para g_para = {
|
||
|
.thread_start = TD_FALSE,
|
||
|
.cnt = 0,
|
||
|
.save_heif = TD_FALSE
|
||
|
};
|
||
|
|
||
|
static struct_venc_qpmap_sendframe_para g_qpmap_send_frame_para;
|
||
|
static pthread_t g_venc_rateauto_pid;
|
||
|
static struct_venc_rateauto_para g_venc_rateauto_frame_param;
|
||
|
static pthread_t g_venc_roimap_pid;
|
||
|
static struct_venc_roimap_frame_para g_roimap_frame_param;
|
||
|
|
||
|
td_s32 g_snap_cnt = 0;
|
||
|
td_char *g_dst_buf = TD_NULL;
|
||
|
|
||
|
#ifdef __READ_ALL_FILE__
|
||
|
static td_s32 read_jpg_file_pos(FILE *fp_jpg, td_char *psz_file, td_s32 size, td_s32 *startpos, td_s32 *endpos)
|
||
|
{
|
||
|
td_s32 i = 0;
|
||
|
td_s32 bufpos = 0;
|
||
|
td_s32 tempbuf[TEMP_BUF_LEN] = { 0 };
|
||
|
td_s32 startflag[2] = { 0xff, 0xd8 }; /* 2 is array size */
|
||
|
td_s32 endflag[2] = { 0xff, 0xd9 }; /* 2 is array size */
|
||
|
|
||
|
if (fread(psz_file, size, 1, fp_jpg) <= 0) {
|
||
|
fclose(fp_jpg);
|
||
|
printf("fread jpeg src fail!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
fclose(fp_jpg);
|
||
|
td_u16 thm_len;
|
||
|
thm_len = (psz_file[0x4] << 0x8) + psz_file[0x5];
|
||
|
while (i < size) {
|
||
|
tempbuf[bufpos] = psz_file[i++];
|
||
|
|
||
|
if (bufpos > 0 && memcmp(tempbuf + bufpos - 1, startflag, sizeof(startflag)) == 0) {
|
||
|
*startpos = i - 0x2;
|
||
|
if (*startpos < 0) {
|
||
|
*startpos = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bufpos > 0 && memcmp(tempbuf + bufpos - 1, endflag, sizeof(endflag)) == 0) {
|
||
|
*endpos = i;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
bufpos++;
|
||
|
|
||
|
if (bufpos == (TEMP_BUF_LEN - 1)) {
|
||
|
if (tempbuf[bufpos - 1] != 0xFF) {
|
||
|
bufpos = 0;
|
||
|
}
|
||
|
} else if (bufpos > (TEMP_BUF_LEN - 1)) {
|
||
|
bufpos = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (*endpos - *startpos <= 0) {
|
||
|
printf("get .thm 11 fail!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (*endpos - *startpos >= size) {
|
||
|
printf("NO DCF info, get .thm 22 fail!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 cpy_jpg_file_by_pos(td_char *psz_file, td_s32 startpos, td_s32 endpos)
|
||
|
{
|
||
|
td_char *temp = psz_file + startpos;
|
||
|
if (MAX_THM_SIZE < (endpos - startpos)) {
|
||
|
printf("thm is too large than MAX_THM_SIZE, get .thm 33 fail!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
td_char *c_dst_buf = (td_char *)malloc(endpos - startpos);
|
||
|
if (c_dst_buf == TD_NULL) {
|
||
|
printf("memory malloc fail!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (memcpy_s(c_dst_buf, endpos - startpos, temp, endpos - startpos) != EOK) {
|
||
|
printf("call memcpy_s error\n");
|
||
|
free(c_dst_buf);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
g_dst_buf = c_dst_buf;
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 file_trans_get_thm_from_jpg(td_char *jpg_path, td_u8 len, td_u32 *dst_size)
|
||
|
{
|
||
|
td_s32 ret = TD_FAILURE;
|
||
|
FILE *fp_jpg = TD_NULL;
|
||
|
td_s32 startpos = 0;
|
||
|
td_s32 endpos = 0;
|
||
|
td_char *psz_file = TD_NULL;
|
||
|
td_s32 fd;
|
||
|
struct stat stat_info = {0};
|
||
|
td_char real_path[PATH_MAX];
|
||
|
|
||
|
if (realpath(jpg_path, real_path) == TD_NULL) {
|
||
|
printf("file %s error!\n", real_path);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
fp_jpg = fopen(real_path, "rb");
|
||
|
if (fp_jpg == TD_NULL) {
|
||
|
printf("file %s not exist!\n", real_path);
|
||
|
return TD_FAILURE;
|
||
|
} else {
|
||
|
fd = fileno(fp_jpg);
|
||
|
fchmod(fd, S_IRUSR | S_IWUSR);
|
||
|
fstat(fd, &stat_info);
|
||
|
psz_file = (td_char *)malloc(stat_info.size);
|
||
|
if ((psz_file == TD_NULL) || (stat_info.size < 6)) { /* 6: algo num */
|
||
|
fclose(fp_jpg);
|
||
|
printf("memory malloc fail!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
ret = read_jpg_file_pos(fp_jpg, psz_file, stat_info.size, &startpos, &endpos);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
free(psz_file);
|
||
|
printf("read_jpg_file_pos fail!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ret = cpy_jpg_file_by_pos(psz_file, startpos, endpos)
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
free(psz_file);
|
||
|
printf("cpy_jpg_file_by_pos fail!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
*dst_size = endpos - startpos;
|
||
|
free(psz_file);
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
|
||
|
static td_void file_trans_set_tembuf(FILE *fp_jpg, struct stat *stat_info, td_s32 *startpos, td_s32 *endpos)
|
||
|
{
|
||
|
td_s32 tempbuf[TEMP_BUF_LEN] = { 0 };
|
||
|
td_s32 fd, ret;
|
||
|
td_s32 bufpos = 0;
|
||
|
td_s32 startflag[2] = { 0xff, 0xd8 }; /* 2 is a number */
|
||
|
td_s32 endflag[2] = { 0xff, 0xd9 }; /* 2 is a number */
|
||
|
td_bool start_match = TD_FALSE;
|
||
|
|
||
|
fd = fileno(fp_jpg);
|
||
|
fchmod(fd, S_IRUSR | S_IWUSR);
|
||
|
fstat(fd, stat_info);
|
||
|
|
||
|
while (!feof(fp_jpg)) {
|
||
|
tempbuf[bufpos] = getc(fp_jpg);
|
||
|
if (bufpos > 0) {
|
||
|
if (memcmp(tempbuf + bufpos - 1, startflag, sizeof(startflag)) == 0) {
|
||
|
*startpos = ((ftell(fp_jpg) - 2) < 0) ? 0 : (ftell(fp_jpg) - 2); /* 2 is a number 2 is a number */
|
||
|
start_match = TD_TRUE;
|
||
|
}
|
||
|
|
||
|
ret = memcmp(tempbuf + bufpos - 1, endflag, sizeof(endflag));
|
||
|
if ((ret == 0) && (start_match == TD_TRUE)) {
|
||
|
*endpos = ftell(fp_jpg);
|
||
|
break;
|
||
|
} else if ((ret == 0) && (start_match != TD_TRUE)) {
|
||
|
*endpos = ftell(fp_jpg);
|
||
|
}
|
||
|
}
|
||
|
bufpos++;
|
||
|
|
||
|
if (bufpos == (TEMP_BUF_LEN - 1)) {
|
||
|
if (tempbuf[bufpos - 1] != 0xFF) {
|
||
|
bufpos = 0;
|
||
|
}
|
||
|
} else if (bufpos > (TEMP_BUF_LEN - 1)) {
|
||
|
if (tempbuf[bufpos - 1] == 0xFF) {
|
||
|
tempbuf[0] = 0xFF;
|
||
|
bufpos = 1;
|
||
|
} else {
|
||
|
bufpos = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static td_s32 file_trans_get_thm_from_jpg(td_char *jpg_path, td_u8 len, td_u32 *dst_size)
|
||
|
{
|
||
|
td_s32 startpos = 0;
|
||
|
td_s32 endpos = 0;
|
||
|
|
||
|
struct stat stat_info = {0};
|
||
|
|
||
|
FILE *fp_jpg = TD_NULL;
|
||
|
td_char real_path[PATH_MAX];
|
||
|
|
||
|
if ((len > FILE_NAME_LEN) || realpath(jpg_path, real_path) == TD_NULL) {
|
||
|
printf("file %s error!\n", jpg_path);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
fp_jpg = fopen(real_path, "rb");
|
||
|
if (fp_jpg == TD_NULL) {
|
||
|
printf("file %s not exist!\n", real_path);
|
||
|
return TD_FAILURE;
|
||
|
} else {
|
||
|
file_trans_set_tembuf(fp_jpg, &stat_info, &startpos, &endpos);
|
||
|
}
|
||
|
|
||
|
if (endpos - startpos <= 0) {
|
||
|
printf("get .thm 11 fail!\n");
|
||
|
fclose(fp_jpg);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (endpos - startpos > MAX_THM_SIZE) {
|
||
|
printf("thm is too large than MAX_THM_SIZE, get .thm 22 fail!\n");
|
||
|
fclose(fp_jpg);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (endpos - startpos >= stat_info.st_size) {
|
||
|
printf("NO DCF info, get .thm 33 fail!\n");
|
||
|
fclose(fp_jpg);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
td_char *c_dst_buf = (td_char *)malloc(endpos - startpos);
|
||
|
if (c_dst_buf == TD_NULL) {
|
||
|
printf("memory malloc fail!\n");
|
||
|
fclose(fp_jpg);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
fseek(fp_jpg, (long)startpos, SEEK_SET);
|
||
|
*dst_size = fread(c_dst_buf, 1, endpos - startpos, fp_jpg);
|
||
|
if (*dst_size != (td_u32)(endpos - startpos)) {
|
||
|
free(c_dst_buf);
|
||
|
printf("fread fail!\n");
|
||
|
fclose(fp_jpg);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
g_dst_buf = c_dst_buf;
|
||
|
fclose(fp_jpg);
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* set venc memory location */
|
||
|
td_s32 sample_comm_venc_mem_config(td_void)
|
||
|
{
|
||
|
td_s32 i, ret;
|
||
|
ot_mpp_chn mpp_chn_venc;
|
||
|
|
||
|
/* group, venc max chn is 64 */
|
||
|
for (i = 0; i < 64; i++) {
|
||
|
td_char *pc_mmz_name = TD_NULL;
|
||
|
mpp_chn_venc.mod_id = OT_ID_VENC;
|
||
|
mpp_chn_venc.dev_id = 0;
|
||
|
mpp_chn_venc.chn_id = i;
|
||
|
|
||
|
/* venc */
|
||
|
ret = ss_mpi_sys_set_mem_cfg(&mpp_chn_venc, pc_mmz_name);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_sys_set_mem_config with %#x!\n", ret);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
}
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* get file postfix according palyload_type. */
|
||
|
td_s32 sample_comm_venc_get_file_postfix(ot_payload_type payload, td_char *file_postfix, td_u8 len)
|
||
|
{
|
||
|
if (payload == OT_PT_H264) {
|
||
|
if (strcpy_s(file_postfix, len, ".h264") != EOK) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
} else if (payload == OT_PT_H265) {
|
||
|
if (strcpy_s(file_postfix, len, ".h265") != EOK) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
} else if (payload == OT_PT_JPEG) {
|
||
|
if (strcpy_s(file_postfix, len, ".jpg") != EOK) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
} else if (payload == OT_PT_MJPEG) {
|
||
|
if (strcpy_s(file_postfix, len, ".mjp") != EOK) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
} else {
|
||
|
sample_print("payload type err!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_get_gop_attr(ot_venc_gop_mode gop_mode, ot_venc_gop_attr *gop_attr)
|
||
|
{
|
||
|
switch (gop_mode) {
|
||
|
case OT_VENC_GOP_MODE_NORMAL_P:
|
||
|
gop_attr->gop_mode = OT_VENC_GOP_MODE_NORMAL_P;
|
||
|
gop_attr->normal_p.ip_qp_delta = 2; /* 2 is a number */
|
||
|
break;
|
||
|
|
||
|
case OT_VENC_GOP_MODE_SMART_P:
|
||
|
gop_attr->gop_mode = OT_VENC_GOP_MODE_SMART_P;
|
||
|
gop_attr->smart_p.bg_qp_delta = 4; /* 4 is a number */
|
||
|
gop_attr->smart_p.vi_qp_delta = 2; /* 2 is a number */
|
||
|
gop_attr->smart_p.bg_interval = 90; /* 90 is a number */
|
||
|
break;
|
||
|
|
||
|
case OT_VENC_GOP_MODE_DUAL_P:
|
||
|
gop_attr->gop_mode = OT_VENC_GOP_MODE_DUAL_P;
|
||
|
gop_attr->dual_p.ip_qp_delta = 4; /* 4 is a number */
|
||
|
gop_attr->dual_p.sp_qp_delta = 2; /* 2 is a number */
|
||
|
gop_attr->dual_p.sp_interval = 3; /* 3 is a number */
|
||
|
break;
|
||
|
|
||
|
case OT_VENC_GOP_MODE_BIPRED_B:
|
||
|
gop_attr->gop_mode = OT_VENC_GOP_MODE_BIPRED_B;
|
||
|
gop_attr->bipred_b.b_qp_delta = -2; /* -2 is a number */
|
||
|
gop_attr->bipred_b.ip_qp_delta = 3; /* 3 is a number */
|
||
|
gop_attr->bipred_b.b_frame_num = 2; /* 2 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
sample_print("not support the gop mode !\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_get_dcf_info(td_char *src_jpg_path, td_u32 src_len, td_char *dst_thm_path, td_u32 dst_len)
|
||
|
{
|
||
|
td_s32 rtn_val, fd;
|
||
|
td_char jpg_src_path[FILE_NAME_LEN] = {0};
|
||
|
td_char jpg_des_path[FILE_NAME_LEN] = {0};
|
||
|
td_u32 dst_size = 0;
|
||
|
if (snprintf_s(jpg_src_path, sizeof(jpg_src_path), src_len - 1, "%s", src_jpg_path) < 0) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (snprintf_s(jpg_des_path, sizeof(jpg_des_path), dst_len - 1, "%s", dst_thm_path) < 0) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
rtn_val = file_trans_get_thm_from_jpg(jpg_src_path, FILE_NAME_LEN, &dst_size);
|
||
|
if ((rtn_val != TD_SUCCESS) || (dst_size == 0)) {
|
||
|
printf("fail to get thm\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
FILE *fp_thm = fopen(jpg_des_path, "w");
|
||
|
if (fp_thm == TD_NULL) {
|
||
|
printf("file to create file %s\n", jpg_des_path);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
fd = fileno(fp_thm);
|
||
|
fchmod(fd, S_IRUSR | S_IWUSR);
|
||
|
|
||
|
td_u32 writen_size = 0;
|
||
|
|
||
|
while (writen_size < dst_size) {
|
||
|
rtn_val = fwrite(g_dst_buf + writen_size, 1, dst_size, fp_thm);
|
||
|
if (rtn_val <= 0) {
|
||
|
printf("fail to write file, rtn=%d\n", rtn_val);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
writen_size += rtn_val;
|
||
|
}
|
||
|
|
||
|
if (fp_thm != TD_NULL) {
|
||
|
fclose(fp_thm);
|
||
|
fp_thm = 0;
|
||
|
}
|
||
|
|
||
|
if (g_dst_buf != TD_NULL) {
|
||
|
free(g_dst_buf);
|
||
|
g_dst_buf = TD_NULL;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_save_stream(FILE *fd, ot_venc_stream *stream)
|
||
|
{
|
||
|
td_u32 i;
|
||
|
|
||
|
for (i = 0; i < stream->pack_cnt; i++) {
|
||
|
fwrite(stream->pack[i].addr + stream->pack[i].offset, stream->pack[i].len - stream->pack[i].offset, 1, fd);
|
||
|
|
||
|
fflush(fd);
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_venc_phys_addr_retrace(FILE *fd, ot_venc_stream_buf_info *stream_buf, ot_venc_stream *stream,
|
||
|
td_u32 i, td_u32 j)
|
||
|
{
|
||
|
td_u64 src_phys_addr;
|
||
|
td_u32 left;
|
||
|
td_s32 ret;
|
||
|
|
||
|
if (stream->pack[i].phys_addr + stream->pack[i].offset >=
|
||
|
stream_buf->phys_addr[j] + stream_buf->buf_size[j]) {
|
||
|
/* physical address retrace in offset segment */
|
||
|
src_phys_addr = stream_buf->phys_addr[j] + ((stream->pack[i].phys_addr + stream->pack[i].offset) -
|
||
|
(stream_buf->phys_addr[j] + stream_buf->buf_size[j]));
|
||
|
|
||
|
ret = fwrite((td_void *)(td_uintptr_t)src_phys_addr, stream->pack[i].len - stream->pack[i].offset, 1, fd);
|
||
|
if (ret >= 0) {
|
||
|
sample_print("fwrite err %d\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
} else {
|
||
|
/* physical address retrace in data segment */
|
||
|
left = (stream_buf->phys_addr[j] + stream_buf->buf_size[j]) - stream->pack[i].phys_addr;
|
||
|
|
||
|
ret = fwrite((td_void *)(td_uintptr_t)(stream->pack[i].phys_addr + stream->pack[i].offset),
|
||
|
left - stream->pack[i].offset, 1, fd);
|
||
|
if (ret < 0) {
|
||
|
sample_print("fwrite err %d\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
ret = fwrite((td_void *)(td_uintptr_t)stream_buf->phys_addr[j], stream->pack[i].len - left, 1, fd);
|
||
|
if (ret < 0) {
|
||
|
sample_print("fwrite err %d\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* the process of physical address retrace */
|
||
|
td_s32 sample_comm_venc_save_stream_phys_addr(FILE *fd, ot_venc_stream_buf_info *stream_buf, ot_venc_stream *stream)
|
||
|
{
|
||
|
td_u32 i, j;
|
||
|
td_s32 ret;
|
||
|
|
||
|
for (i = 0; i < stream->pack_cnt; i++) {
|
||
|
for (j = 0; j < OT_VENC_MAX_TILE_NUM; j++) {
|
||
|
if ((stream->pack[i].phys_addr > stream_buf->phys_addr[j]) &&
|
||
|
(stream->pack[i].phys_addr <= stream_buf->phys_addr[j] + stream_buf->buf_size[j])) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (j < OT_VENC_MAX_TILE_NUM && stream->pack[i].phys_addr + stream->pack[i].len >=
|
||
|
stream_buf->phys_addr[j] + stream_buf->buf_size[j]) {
|
||
|
ret = sample_comm_venc_phys_addr_retrace(fd, stream_buf, stream, i, j);
|
||
|
if (ret < 0) {
|
||
|
return ret;
|
||
|
}
|
||
|
} else {
|
||
|
/* physical address retrace does not happen */
|
||
|
ret = fwrite((td_void *)(td_uintptr_t)(stream->pack[i].phys_addr + stream->pack[i].offset),
|
||
|
stream->pack[i].len - stream->pack[i].offset, 1, fd);
|
||
|
if (ret < 0) {
|
||
|
sample_print("fwrite err %d\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
fflush(fd);
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_close_reencode(ot_venc_chn venc_chn)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ot_venc_rc_param rc_param;
|
||
|
ot_venc_chn_attr chn_attr;
|
||
|
|
||
|
ret = ss_mpi_venc_get_chn_attr(venc_chn, &chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("GetChnAttr failed!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
ret = ss_mpi_venc_get_rc_param(venc_chn, &rc_param);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("GetRcParam failed!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (chn_attr.rc_attr.rc_mode == OT_VENC_RC_MODE_H264_CBR) {
|
||
|
rc_param.h264_cbr_param.max_reencode_times = 0;
|
||
|
} else if (chn_attr.rc_attr.rc_mode == OT_VENC_RC_MODE_H264_VBR) {
|
||
|
rc_param.h264_vbr_param.max_reencode_times = 0;
|
||
|
} else if (chn_attr.rc_attr.rc_mode == OT_VENC_RC_MODE_H265_CBR) {
|
||
|
rc_param.h265_cbr_param.max_reencode_times = 0;
|
||
|
} else if (chn_attr.rc_attr.rc_mode == OT_VENC_RC_MODE_H265_VBR) {
|
||
|
rc_param.h265_vbr_param.max_reencode_times = 0;
|
||
|
} else {
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
ret = ss_mpi_venc_set_rc_param(venc_chn, &rc_param);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("SetRcParam failed!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
static td_void sample_comm_venc_h264_qpmap_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 frame_rate,
|
||
|
td_u32 stats_time)
|
||
|
{
|
||
|
ot_venc_h264_qpmap h264_qpmap;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H264_QPMAP;
|
||
|
h264_qpmap.gop = gop;
|
||
|
h264_qpmap.stats_time = stats_time;
|
||
|
h264_qpmap.src_frame_rate = frame_rate;
|
||
|
h264_qpmap.dst_frame_rate = frame_rate;
|
||
|
|
||
|
venc_chn_attr->rc_attr.h264_qpmap = h264_qpmap;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h265_qpmap_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 frame_rate,
|
||
|
td_u32 stats_time)
|
||
|
{
|
||
|
ot_venc_h265_qpmap h265_qpmap;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H265_QPMAP;
|
||
|
h265_qpmap.gop = gop;
|
||
|
h265_qpmap.stats_time = stats_time;
|
||
|
h265_qpmap.src_frame_rate = frame_rate;
|
||
|
h265_qpmap.dst_frame_rate = frame_rate;
|
||
|
h265_qpmap.qpmap_mode = OT_VENC_RC_QPMAP_MODE_MEAN_QP;
|
||
|
venc_chn_attr->rc_attr.h265_qpmap = h265_qpmap;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h264_qvbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_h264_qvbr h264_qvbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H264_QVBR;
|
||
|
h264_qvbr.gop = gop;
|
||
|
h264_qvbr.stats_time = stats_time;
|
||
|
h264_qvbr.src_frame_rate = frame_rate;
|
||
|
h264_qvbr.dst_frame_rate = frame_rate;
|
||
|
switch (size) {
|
||
|
case PIC_D1_NTSC:
|
||
|
h264_qvbr.target_bit_rate = 1024 + 512 * frame_rate / 30; /* 1024 512 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
h264_qvbr.target_bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
h264_qvbr.target_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
h264_qvbr.target_bit_rate = 1024 * 3 + 3072 * frame_rate / 30; /* 1024 3 3072 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
h264_qvbr.target_bit_rate = 1024 * 5 + 5120 * frame_rate / 30; /* 1024 5 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
h264_qvbr.target_bit_rate = 1024 * 10 + 5120 * frame_rate / 30; /* 1024 10 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
h264_qvbr.target_bit_rate = 1024 * 20 + 5120 * frame_rate / 30; /* 1024 20 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
h264_qvbr.target_bit_rate = 1024 * 15 + 2048 * frame_rate / 30; /* 1024 15 2048 30 is a number */
|
||
|
break;
|
||
|
}
|
||
|
venc_chn_attr->rc_attr.h264_qvbr = h264_qvbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h265_qvbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_h265_qvbr h265_qvbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H265_QVBR;
|
||
|
h265_qvbr.gop = gop;
|
||
|
h265_qvbr.stats_time = stats_time;
|
||
|
h265_qvbr.src_frame_rate = frame_rate;
|
||
|
h265_qvbr.dst_frame_rate = frame_rate;
|
||
|
switch (size) {
|
||
|
case PIC_D1_NTSC:
|
||
|
h265_qvbr.target_bit_rate = 1024 + 512 * frame_rate / 30; /* 1024 512 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
h265_qvbr.target_bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
h265_qvbr.target_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
h265_qvbr.target_bit_rate = 1024 * 3 + 3072 * frame_rate / 30; /* 1024 3 3072 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
h265_qvbr.target_bit_rate = 1024 * 5 + 5120 * frame_rate / 30; /* 1024 5 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
h265_qvbr.target_bit_rate = 1024 * 10 + 5120 * frame_rate / 30; /* 1024 10 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
h265_qvbr.target_bit_rate = 1024 * 20 + 5120 * frame_rate / 30; /* 1024 20 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
h265_qvbr.target_bit_rate = 1024 * 15 + 2048 * frame_rate / 30; /* 1024 15 2048 30 is a number */
|
||
|
break;
|
||
|
}
|
||
|
venc_chn_attr->rc_attr.h265_qvbr = h265_qvbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_set_h265_cvbr_bit_rate(ot_venc_h264_cvbr *h265_cvbr,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
switch (size) {
|
||
|
case PIC_D1_NTSC:
|
||
|
h265_cvbr->max_bit_rate = 1024 + 512 * frame_rate / 30; /* 1024 512 30 is a number */
|
||
|
h265_cvbr->long_term_max_bit_rate = 1024 + 512 * frame_rate / 30; /* 1024 512 30 is a number */
|
||
|
h265_cvbr->long_term_min_bit_rate = 256; /* 256 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
h265_cvbr->max_bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
h265_cvbr->long_term_max_bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
h265_cvbr->long_term_min_bit_rate = 512; /* 512 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
h265_cvbr->max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
h265_cvbr->long_term_max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
h265_cvbr->long_term_min_bit_rate = 1024; /* 1024 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
h265_cvbr->max_bit_rate = 1024 * 4 + 3072 * frame_rate / 30; /* 1024 4 3072 30 is a number */
|
||
|
h265_cvbr->long_term_max_bit_rate = 1024 * 3 + 3072 * frame_rate / 30; /* 1024 3 3072 30 is a number */
|
||
|
h265_cvbr->long_term_min_bit_rate = 1024 * 2; /* 1024 2 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
h265_cvbr->max_bit_rate = 1024 * 8 + 5120 * frame_rate / 30; /* 1024 8 5120 30 is a number */
|
||
|
h265_cvbr->long_term_max_bit_rate = 1024 * 5 + 5120 * frame_rate / 30; /* 1024 5 5120 30 is a number */
|
||
|
h265_cvbr->long_term_min_bit_rate = 1024 * 3; /* 1024 3 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
h265_cvbr->max_bit_rate = 1024 * 12 + 5120 * frame_rate / 30; /* 1024 12 5120 30 is a number */
|
||
|
h265_cvbr->long_term_max_bit_rate = 1024 * 10 + 5120 * frame_rate / 30; /* 1024 10 5120 30 is a number */
|
||
|
h265_cvbr->long_term_min_bit_rate = 1024 * 4; /* 1024 4 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
h265_cvbr->max_bit_rate = 1024 * 24 + 5120 * frame_rate / 30; /* 1024 24 5120 30 is a number */
|
||
|
h265_cvbr->long_term_max_bit_rate = 1024 * 15 + 5120 * frame_rate / 30; /* 1024 15 5120 30 is a number */
|
||
|
h265_cvbr->long_term_min_bit_rate = 1024 * 5; /* 1024 5 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
h265_cvbr->max_bit_rate = 1024 * 24 + 2048 * frame_rate / 30; /* 1024 24 2048 30 is a number */
|
||
|
h265_cvbr->long_term_max_bit_rate = 1024 * 15 + 2048 * frame_rate / 30; /* 1024 15 2048 30 is a number */
|
||
|
h265_cvbr->long_term_min_bit_rate = 1024 * 5; /* 1024 5 is a number */
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_set_h264_cvbr_bit_rate(ot_venc_h264_cvbr *h264_cvbr,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
switch (size) {
|
||
|
case PIC_D1_NTSC:
|
||
|
h264_cvbr->max_bit_rate = 1024 + 512 * frame_rate / 30; /* 1024 512 30 is a number */
|
||
|
h264_cvbr->long_term_max_bit_rate = 1024 + 512 * frame_rate / 30; /* 1024 512 30 is a number */
|
||
|
h264_cvbr->long_term_min_bit_rate = 256; /* 256 is a number */
|
||
|
break;
|
||
|
case PIC_720P:
|
||
|
h264_cvbr->max_bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
h264_cvbr->long_term_max_bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
h264_cvbr->long_term_min_bit_rate = 512; /* 512 is a number */
|
||
|
break;
|
||
|
case PIC_1080P:
|
||
|
h264_cvbr->max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
h264_cvbr->long_term_max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
h264_cvbr->long_term_min_bit_rate = 1024; /* 1024 is a number */
|
||
|
break;
|
||
|
case PIC_2592X1944:
|
||
|
h264_cvbr->max_bit_rate = 1024 * 4 + 3072 * frame_rate / 30; /* 1024 4 3072 30 is a number */
|
||
|
h264_cvbr->long_term_max_bit_rate = 1024 * 3 + 3072 * frame_rate / 30; /* 1024 3 3072 30 is a number */
|
||
|
h264_cvbr->long_term_min_bit_rate = 1024 * 2; /* 1024 2 is a number */
|
||
|
break;
|
||
|
case PIC_3840X2160:
|
||
|
h264_cvbr->max_bit_rate = 1024 * 8 + 5120 * frame_rate / 30; /* 1024 8 5120 30 is a number */
|
||
|
h264_cvbr->long_term_max_bit_rate = 1024 * 5 + 5120 * frame_rate / 30; /* 1024 5 5120 30 is a number */
|
||
|
h264_cvbr->long_term_min_bit_rate = 1024 * 3; /* 1024 3 is a number */
|
||
|
break;
|
||
|
case PIC_4000X3000:
|
||
|
h264_cvbr->max_bit_rate = 1024 * 12 + 5120 * frame_rate / 30; /* 1024 12 5120 30 is a number */
|
||
|
h264_cvbr->long_term_max_bit_rate = 1024 * 10 + 5120 * frame_rate / 30; /* 1024 10 5120 30 is a number */
|
||
|
h264_cvbr->long_term_min_bit_rate = 1024 * 4; /* 1024 4 is a number */
|
||
|
break;
|
||
|
case PIC_7680X4320:
|
||
|
h264_cvbr->max_bit_rate = 1024 * 24 + 5120 * frame_rate / 30; /* 1024 24 5120 30 is a number */
|
||
|
h264_cvbr->long_term_max_bit_rate = 1024 * 15 + 5120 * frame_rate / 30; /* 1024 15 5120 30 is a number */
|
||
|
h264_cvbr->long_term_min_bit_rate = 1024 * 5; /* 1024 5 is a number */
|
||
|
break;
|
||
|
default:
|
||
|
h264_cvbr->max_bit_rate = 1024 * 24 + 2048 * frame_rate / 30; /* 1024 24 2048 30 is a number */
|
||
|
h264_cvbr->long_term_max_bit_rate = 1024 * 15 + 2048 * frame_rate / 30; /* 1024 15 2048 30 is a number */
|
||
|
h264_cvbr->long_term_min_bit_rate = 1024 * 5; /* 1024 5 is a number */
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h264_cvbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_h264_cvbr h264_cvbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H264_CVBR;
|
||
|
h264_cvbr.gop = gop;
|
||
|
h264_cvbr.stats_time = stats_time;
|
||
|
h264_cvbr.src_frame_rate = frame_rate;
|
||
|
h264_cvbr.dst_frame_rate = frame_rate;
|
||
|
h264_cvbr.long_term_stats_time = 1;
|
||
|
h264_cvbr.short_term_stats_time = stats_time;
|
||
|
|
||
|
sample_comm_venc_set_h264_cvbr_bit_rate(&h264_cvbr, frame_rate, size);
|
||
|
|
||
|
venc_chn_attr->rc_attr.h264_cvbr = h264_cvbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h265_cvbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_h265_cvbr h265_cvbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H265_CVBR;
|
||
|
h265_cvbr.gop = gop;
|
||
|
h265_cvbr.stats_time = stats_time;
|
||
|
h265_cvbr.src_frame_rate = frame_rate;
|
||
|
h265_cvbr.dst_frame_rate = frame_rate;
|
||
|
h265_cvbr.long_term_stats_time = 1;
|
||
|
h265_cvbr.short_term_stats_time = stats_time;
|
||
|
|
||
|
sample_comm_venc_set_h265_cvbr_bit_rate(&h265_cvbr, frame_rate, size);
|
||
|
|
||
|
venc_chn_attr->rc_attr.h265_cvbr = h265_cvbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h264_avbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_h264_avbr h264_avbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H264_AVBR;
|
||
|
h264_avbr.gop = gop;
|
||
|
h264_avbr.stats_time = stats_time;
|
||
|
h264_avbr.src_frame_rate = frame_rate;
|
||
|
h264_avbr.dst_frame_rate = frame_rate;
|
||
|
switch (size) {
|
||
|
case PIC_360P:
|
||
|
h264_avbr.max_bit_rate = 1024 * 1 + 1024 * frame_rate / 30; /* 1024 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_D1_NTSC:
|
||
|
h264_avbr.max_bit_rate = 1024 * frame_rate / 30; /* 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
h264_avbr.max_bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
h264_avbr.max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
h264_avbr.max_bit_rate = 1024 * 3 + 3072 * frame_rate / 30; /* 1024 3 3072 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
h264_avbr.max_bit_rate = 1024 * 5 + 5120 * frame_rate / 30; /* 1024 5 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
h264_avbr.max_bit_rate = 1024 * 10 + 5120 * frame_rate / 30; /* 1024 10 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
h264_avbr.max_bit_rate = 1024 * 20 + 5120 * frame_rate / 30; /* 1024 20 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
h264_avbr.max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
venc_chn_attr->rc_attr.h264_avbr = h264_avbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h265_avbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_h265_avbr h265_avbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H265_AVBR;
|
||
|
h265_avbr.gop = gop;
|
||
|
h265_avbr.stats_time = stats_time;
|
||
|
h265_avbr.src_frame_rate = frame_rate;
|
||
|
h265_avbr.dst_frame_rate = frame_rate;
|
||
|
|
||
|
switch (size) {
|
||
|
case PIC_D1_NTSC:
|
||
|
h265_avbr.max_bit_rate = 1024 * frame_rate / 30; /* 1024 is a number 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
h265_avbr.max_bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
h265_avbr.max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
h265_avbr.max_bit_rate = 1024 * 3 + 3072 * frame_rate / 30; /* 1024 3 3072 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
h265_avbr.max_bit_rate = 1024 * 5 + 5120 * frame_rate / 30; /* 1024 5 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
h265_avbr.max_bit_rate = 1024 * 10 + 5120 * frame_rate / 30; /* 1024 10 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
h265_avbr.max_bit_rate = 1024 * 20 + 5120 * frame_rate / 30; /* 1024 20 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
h265_avbr.max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
}
|
||
|
venc_chn_attr->rc_attr.h265_avbr = h265_avbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_mjpeg_vbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_mjpeg_vbr mjpeg_vbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_MJPEG_VBR;
|
||
|
mjpeg_vbr.stats_time = stats_time;
|
||
|
mjpeg_vbr.src_frame_rate = frame_rate;
|
||
|
mjpeg_vbr.dst_frame_rate = 5; /* 5 is a number */
|
||
|
|
||
|
switch (size) {
|
||
|
case PIC_360P:
|
||
|
mjpeg_vbr.max_bit_rate = 1024 * 3 + 1024 * frame_rate / 30; /* 1024 3 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_D1_NTSC:
|
||
|
mjpeg_vbr.max_bit_rate = 1024 + 1024 * frame_rate / 30; /* 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
mjpeg_vbr.max_bit_rate = 1024 * 3 + 1024 * frame_rate / 30; /* 1024 3 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
mjpeg_vbr.max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
mjpeg_vbr.max_bit_rate = 1024 * 20 + 3072 * frame_rate / 30; /* 1024 20 3072 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
mjpeg_vbr.max_bit_rate = 1024 * 25 + 5120 * frame_rate / 30; /* 1024 25 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
mjpeg_vbr.max_bit_rate = 1024 * 30 + 5120 * frame_rate / 30; /* 1024 30 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
mjpeg_vbr.max_bit_rate = 1024 * 40 + 5120 * frame_rate / 30; /* 1024 40 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
mjpeg_vbr.max_bit_rate = 1024 * 5 + 2048 * frame_rate / 30; /* 1024 5 2048 30 is a number */
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
venc_chn_attr->rc_attr.mjpeg_vbr = mjpeg_vbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h264_vbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_h264_vbr h264_vbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H264_VBR;
|
||
|
h264_vbr.gop = gop;
|
||
|
h264_vbr.stats_time = stats_time;
|
||
|
h264_vbr.src_frame_rate = frame_rate;
|
||
|
h264_vbr.dst_frame_rate = frame_rate;
|
||
|
switch (size) {
|
||
|
case PIC_360P:
|
||
|
h264_vbr.max_bit_rate = 1024 * 1 + 1024 * frame_rate / 30; /* 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_D1_NTSC:
|
||
|
h264_vbr.max_bit_rate = 1024 * frame_rate / 30; /* 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
h264_vbr.max_bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
h264_vbr.max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
h264_vbr.max_bit_rate = 1024 * 3 + 3072 * frame_rate / 30; /* 1024 3 3072 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
h264_vbr.max_bit_rate = 1024 * 5 + 5120 * frame_rate / 30; /* 1024 5 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
h264_vbr.max_bit_rate = 1024 * 10 + 5120 * frame_rate / 30; /* 1024 10 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
h264_vbr.max_bit_rate = 1024 * 20 + 5120 * frame_rate / 30; /* 1024 20 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
h264_vbr.max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
venc_chn_attr->rc_attr.h264_vbr = h264_vbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h265_vbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_h265_vbr h265_vbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H265_VBR;
|
||
|
h265_vbr.gop = gop;
|
||
|
h265_vbr.stats_time = stats_time;
|
||
|
h265_vbr.src_frame_rate = frame_rate;
|
||
|
h265_vbr.dst_frame_rate = frame_rate;
|
||
|
switch (size) {
|
||
|
case PIC_D1_NTSC:
|
||
|
h265_vbr.max_bit_rate = 1024 * frame_rate / 30; /* 1024 is a number 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
h265_vbr.max_bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
h265_vbr.max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
h265_vbr.max_bit_rate = 1024 * 3 + 3072 * frame_rate / 30; /* 1024 3 is 3072 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
h265_vbr.max_bit_rate = 1024 * 5 + 5120 * frame_rate / 30; /* 1024 5 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
h265_vbr.max_bit_rate = 1024 * 10 + 5120 * frame_rate / 30; /* 1024 10 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
h265_vbr.max_bit_rate = 1024 * 20 + 5120 * frame_rate / 30; /* 1024 20 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
h265_vbr.max_bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
}
|
||
|
venc_chn_attr->rc_attr.h265_vbr = h265_vbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_mjpeg_fixqp_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 frame_rate)
|
||
|
{
|
||
|
ot_venc_mjpeg_fixqp mjpege_fixqp;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_MJPEG_FIXQP;
|
||
|
mjpege_fixqp.qfactor = 95; /* 95 is a number */
|
||
|
mjpege_fixqp.src_frame_rate = frame_rate;
|
||
|
mjpege_fixqp.dst_frame_rate = frame_rate;
|
||
|
|
||
|
venc_chn_attr->rc_attr.mjpeg_fixqp = mjpege_fixqp;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h264_fixqp_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 frame_rate)
|
||
|
{
|
||
|
ot_venc_h264_fixqp h264_fixqp;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H264_FIXQP;
|
||
|
h264_fixqp.gop = gop;
|
||
|
h264_fixqp.src_frame_rate = frame_rate;
|
||
|
h264_fixqp.dst_frame_rate = frame_rate;
|
||
|
h264_fixqp.i_qp = 25; /* 25 is a number */
|
||
|
h264_fixqp.p_qp = 30; /* 30 is a number */
|
||
|
h264_fixqp.b_qp = 32; /* 32 is a number */
|
||
|
venc_chn_attr->rc_attr.h264_fixqp = h264_fixqp;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h265_fixqp_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 frame_rate)
|
||
|
{
|
||
|
ot_venc_h265_fixqp h265_fixqp;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H265_FIXQP;
|
||
|
h265_fixqp.gop = gop;
|
||
|
h265_fixqp.src_frame_rate = frame_rate;
|
||
|
h265_fixqp.dst_frame_rate = frame_rate;
|
||
|
h265_fixqp.i_qp = 25; /* 25 is a number */
|
||
|
h265_fixqp.p_qp = 30; /* 30 is a number */
|
||
|
h265_fixqp.b_qp = 32; /* 32 is a number */
|
||
|
venc_chn_attr->rc_attr.h265_fixqp = h265_fixqp;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_mjpeg_cbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_mjpeg_cbr mjpege_cbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_MJPEG_CBR;
|
||
|
mjpege_cbr.stats_time = stats_time;
|
||
|
mjpege_cbr.src_frame_rate = frame_rate;
|
||
|
mjpege_cbr.dst_frame_rate = frame_rate;
|
||
|
|
||
|
switch (size) {
|
||
|
case PIC_360P:
|
||
|
mjpege_cbr.bit_rate = 1024 * 3 + 1024 * frame_rate / 30; /* 1024 3 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_D1_NTSC:
|
||
|
mjpege_cbr.bit_rate = 1024 + 1024 * frame_rate / 30; /* 1024 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
mjpege_cbr.bit_rate = 1024 * 3 + 1024 * frame_rate / 30; /* 1024 3 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
mjpege_cbr.bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
mjpege_cbr.bit_rate = 1024 * 20 + 3072 * frame_rate / 30; /* 1024 20 3072 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
mjpege_cbr.bit_rate = 1024 * 25 + 5120 * frame_rate / 30; /* 1024 25 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
mjpege_cbr.bit_rate = 1024 * 30 + 5120 * frame_rate / 30; /* 1024 30 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
mjpege_cbr.bit_rate = 1024 * 40 + 5120 * frame_rate / 30; /* 1024 40 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
mjpege_cbr.bit_rate = 1024 * 5 + 2048 * frame_rate / 30; /* 1024 5 2048 30 is a number */
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
venc_chn_attr->rc_attr.mjpeg_cbr = mjpege_cbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h264_cbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_h264_cbr h264_cbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H264_CBR;
|
||
|
h264_cbr.gop = gop;
|
||
|
h264_cbr.stats_time = stats_time; /* stream rate statics time(s) */
|
||
|
h264_cbr.src_frame_rate = frame_rate; /* input (vi) frame rate */
|
||
|
h264_cbr.dst_frame_rate = frame_rate; /* target frame rate */
|
||
|
switch (size) {
|
||
|
case PIC_360P:
|
||
|
h264_cbr.bit_rate = 1024 * 1 + 1024 * frame_rate / 30; /* 1024 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_D1_NTSC:
|
||
|
h264_cbr.bit_rate = 1024 * frame_rate / 30; /* 1024 is 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
h264_cbr.bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
h264_cbr.bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
h264_cbr.bit_rate = 1024 * 3 + 3072 * frame_rate / 30; /* 1024 3 3072 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
h264_cbr.bit_rate = 1024 * 5 + 5120 * frame_rate / 30; /* 1024 5 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
h264_cbr.bit_rate = 1024 * 12 + 5120 * frame_rate / 30; /* 1024 12 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
h264_cbr.bit_rate = 1024 * 10 + 5120 * frame_rate / 30; /* 1024 10 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
h264_cbr.bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
venc_chn_attr->rc_attr.h264_cbr = h264_cbr;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_h265_cbr_param_init(ot_venc_chn_attr *venc_chn_attr, td_u32 gop, td_u32 stats_time,
|
||
|
td_u32 frame_rate, ot_enum_pic_size size)
|
||
|
{
|
||
|
ot_venc_h265_cbr h265_cbr;
|
||
|
|
||
|
venc_chn_attr->rc_attr.rc_mode = OT_VENC_RC_MODE_H265_CBR;
|
||
|
h265_cbr.gop = gop;
|
||
|
h265_cbr.stats_time = stats_time; /* stream rate statics time(s) */
|
||
|
h265_cbr.src_frame_rate = frame_rate; /* input (vi) frame rate */
|
||
|
h265_cbr.dst_frame_rate = frame_rate; /* target frame rate */
|
||
|
switch (size) {
|
||
|
case PIC_D1_NTSC:
|
||
|
h265_cbr.bit_rate = 1024 * frame_rate / 30; /* 1024 is a number 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_720P:
|
||
|
h265_cbr.bit_rate = 1024 * 2 + 1024 * frame_rate / 30; /* 1024 2 1024 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_1080P:
|
||
|
h265_cbr.bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_2592X1944:
|
||
|
h265_cbr.bit_rate = 1024 * 3 + 3072 * frame_rate / 30; /* 1024 3 3072 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_3840X2160:
|
||
|
h265_cbr.bit_rate = 1024 * 5 + 5120 * frame_rate / 30; /* 1024 5 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_4000X3000:
|
||
|
h265_cbr.bit_rate = 1024 * 10 + 5120 * frame_rate / 30; /* 1024 10 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
case PIC_7680X4320:
|
||
|
h265_cbr.bit_rate = 1024 * 20 + 5120 * frame_rate / 30; /* 1024 20 5120 30 is a number */
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
h265_cbr.bit_rate = 1024 * 2 + 2048 * frame_rate / 30; /* 1024 2 2048 30 is a number */
|
||
|
break;
|
||
|
}
|
||
|
venc_chn_attr->rc_attr.h265_cbr = h265_cbr;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_venc_jpeg_param_init(ot_venc_chn_attr *venc_chn_attr)
|
||
|
{
|
||
|
ot_venc_jpeg_attr jpeg_attr;
|
||
|
jpeg_attr.dcf_en = TD_FALSE;
|
||
|
jpeg_attr.mpf_cfg.large_thumbnail_num = 0;
|
||
|
jpeg_attr.recv_mode = OT_VENC_PIC_RECV_SINGLE;
|
||
|
|
||
|
venc_chn_attr->venc_attr.jpeg_attr = jpeg_attr;
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
static td_s32 sample_comm_venc_mjpeg_param_init(ot_venc_chn_attr *venc_chn_attr,
|
||
|
struct_comm_venc_chn_param *venc_create_chn_param)
|
||
|
{
|
||
|
enum_rc rc_mode = venc_create_chn_param->rc_mode;
|
||
|
td_u32 stats_time = venc_create_chn_param->stats_time;
|
||
|
td_u32 frame_rate = venc_create_chn_param->frame_rate;
|
||
|
ot_enum_pic_size size = venc_create_chn_param->size;
|
||
|
|
||
|
if (rc_mode == SAMPLE_RC_FIXQP) {
|
||
|
sample_comm_venc_mjpeg_fixqp_param_init(venc_chn_attr, frame_rate);
|
||
|
} else if (rc_mode == SAMPLE_RC_CBR) {
|
||
|
sample_comm_venc_mjpeg_cbr_param_init(venc_chn_attr, stats_time, frame_rate, size);
|
||
|
} else if ((rc_mode == SAMPLE_RC_VBR) || (rc_mode == SAMPLE_RC_AVBR)) {
|
||
|
if (rc_mode == SAMPLE_RC_AVBR) {
|
||
|
sample_print("mjpege not support AVBR, so change rcmode to VBR!\n");
|
||
|
}
|
||
|
sample_comm_venc_mjpeg_vbr_param_init(venc_chn_attr, stats_time, frame_rate, size);
|
||
|
} else {
|
||
|
sample_print("can't support other mode(%d) in this version!\n", rc_mode);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_venc_h264_param_init(ot_venc_chn_attr *chn_attr, struct_comm_venc_chn_param *chn_param)
|
||
|
{
|
||
|
enum_rc rc_mode = chn_param->rc_mode;
|
||
|
td_u32 gop = chn_param->gop;
|
||
|
td_u32 stats_time = chn_param->stats_time;
|
||
|
td_u32 frame_rate = chn_param->frame_rate;
|
||
|
ot_enum_pic_size size = chn_param->size;
|
||
|
|
||
|
chn_attr->venc_attr.h264_attr.frame_buf_ratio = SAMPLE_FRAME_BUF_RATIO_MIN;
|
||
|
if (rc_mode == SAMPLE_RC_CBR) {
|
||
|
sample_comm_venc_h264_cbr_param_init(chn_attr, gop, stats_time, frame_rate, size);
|
||
|
} else if (rc_mode == SAMPLE_RC_FIXQP) {
|
||
|
sample_comm_venc_h264_fixqp_param_init(chn_attr, gop, frame_rate);
|
||
|
} else if (rc_mode == SAMPLE_RC_VBR) {
|
||
|
sample_comm_venc_h264_vbr_param_init(chn_attr, gop, stats_time, frame_rate, size);
|
||
|
} else if (rc_mode == SAMPLE_RC_AVBR) {
|
||
|
sample_comm_venc_h264_avbr_param_init(chn_attr, gop, stats_time, frame_rate, size);
|
||
|
} else if (rc_mode == SAMPLE_RC_CVBR) {
|
||
|
sample_comm_venc_h264_cvbr_param_init(chn_attr, gop, stats_time, frame_rate, size);
|
||
|
} else if (rc_mode == SAMPLE_RC_QVBR) {
|
||
|
sample_comm_venc_h264_qvbr_param_init(chn_attr, gop, stats_time, frame_rate, size);
|
||
|
} else if (rc_mode == SAMPLE_RC_QPMAP) {
|
||
|
sample_comm_venc_h264_qpmap_param_init(chn_attr, gop, frame_rate, stats_time);
|
||
|
} else {
|
||
|
sample_print("%s,%d,rc_mode(%d) not support\n", __FUNCTION__, __LINE__, rc_mode);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
chn_attr->venc_attr.h264_attr.rcn_ref_share_buf_en = chn_param->is_rcn_ref_share_buf;
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_venc_h265_param_init(ot_venc_chn_attr *chn_attr,
|
||
|
struct_comm_venc_chn_param *chn_param)
|
||
|
{
|
||
|
enum_rc rc_mode = chn_param->rc_mode;
|
||
|
td_u32 gop = chn_param->gop;
|
||
|
td_u32 stats_time = chn_param->stats_time;
|
||
|
td_u32 frame_rate = chn_param->frame_rate;
|
||
|
ot_enum_pic_size size = chn_param->size;
|
||
|
|
||
|
chn_attr->venc_attr.h265_attr.frame_buf_ratio = SAMPLE_FRAME_BUF_RATIO_MIN;
|
||
|
if (rc_mode == SAMPLE_RC_CBR) {
|
||
|
sample_comm_venc_h265_cbr_param_init(chn_attr, gop, stats_time, frame_rate, size);
|
||
|
} else if (rc_mode == SAMPLE_RC_FIXQP) {
|
||
|
sample_comm_venc_h265_fixqp_param_init(chn_attr, gop, frame_rate);
|
||
|
} else if (rc_mode == SAMPLE_RC_VBR) {
|
||
|
sample_comm_venc_h265_vbr_param_init(chn_attr, gop, stats_time, frame_rate, size);
|
||
|
} else if (rc_mode == SAMPLE_RC_AVBR) {
|
||
|
sample_comm_venc_h265_avbr_param_init(chn_attr, gop, stats_time, frame_rate, size);
|
||
|
} else if (rc_mode == SAMPLE_RC_CVBR) {
|
||
|
sample_comm_venc_h265_cvbr_param_init(chn_attr, gop, stats_time, frame_rate, size);
|
||
|
} else if (rc_mode == SAMPLE_RC_QVBR) {
|
||
|
sample_comm_venc_h265_qvbr_param_init(chn_attr, gop, stats_time, frame_rate, size);
|
||
|
} else if (rc_mode == SAMPLE_RC_QPMAP) {
|
||
|
sample_comm_venc_h265_qpmap_param_init(chn_attr, gop, frame_rate, stats_time);
|
||
|
} else {
|
||
|
sample_print("%s,%d,rc_mode(%d) not support\n", __FUNCTION__, __LINE__, rc_mode);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
chn_attr->venc_attr.h265_attr.rcn_ref_share_buf_en = chn_param->is_rcn_ref_share_buf;
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_set_gop_attr(ot_payload_type type, ot_venc_chn_attr *chn_attr,
|
||
|
ot_venc_gop_attr *gop_attr)
|
||
|
{
|
||
|
if (type == OT_PT_MJPEG || type == OT_PT_JPEG) {
|
||
|
chn_attr->gop_attr.gop_mode = OT_VENC_GOP_MODE_NORMAL_P;
|
||
|
chn_attr->gop_attr.normal_p.ip_qp_delta = 0;
|
||
|
} else {
|
||
|
chn_attr->gop_attr = *gop_attr;
|
||
|
if ((gop_attr->gop_mode == OT_VENC_GOP_MODE_BIPRED_B) && (type == OT_PT_H264)) {
|
||
|
if (chn_attr->venc_attr.profile == 0) {
|
||
|
chn_attr->venc_attr.profile = 1;
|
||
|
|
||
|
sample_print("H.264 base profile not support BIPREDB, so change profile to main profile!\n");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_venc_channel_param_init(struct_comm_venc_chn_param *chn_param, ot_venc_chn_attr *chn_attr)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ot_venc_gop_attr *gop_attr = &chn_param->gop_attr;
|
||
|
td_u32 profile = chn_param->profile;
|
||
|
ot_payload_type type = chn_param->type;
|
||
|
ot_size venc_size = chn_param->venc_size;
|
||
|
|
||
|
chn_attr->venc_attr.type = type;
|
||
|
chn_attr->venc_attr.max_pic_width = venc_size.width;
|
||
|
chn_attr->venc_attr.max_pic_height = venc_size.height;
|
||
|
chn_attr->venc_attr.pic_width = venc_size.width; /* the picture width */
|
||
|
chn_attr->venc_attr.pic_height = venc_size.height; /* the picture height */
|
||
|
|
||
|
if (type == OT_PT_MJPEG || type == OT_PT_JPEG) {
|
||
|
chn_attr->venc_attr.buf_size =
|
||
|
OT_ALIGN_UP(venc_size.width, 16) * OT_ALIGN_UP(venc_size.height, 16) * 4; /* 16 4 is a number */
|
||
|
} else {
|
||
|
chn_attr->venc_attr.buf_size =
|
||
|
OT_ALIGN_UP(venc_size.width * venc_size.height * 3 / 4, 64); /* 3 4 64 is a number */
|
||
|
}
|
||
|
chn_attr->venc_attr.profile = profile;
|
||
|
chn_attr->venc_attr.is_by_frame = TD_TRUE; /* get stream mode is slice mode or frame mode? */
|
||
|
|
||
|
if (gop_attr->gop_mode == OT_VENC_GOP_MODE_SMART_P) {
|
||
|
chn_param->stats_time = gop_attr->smart_p.bg_interval / chn_param->gop;
|
||
|
} else {
|
||
|
chn_param->stats_time = 1;
|
||
|
}
|
||
|
|
||
|
switch (type) {
|
||
|
case OT_PT_H265:
|
||
|
ret = sample_comm_venc_h265_param_init(chn_attr, chn_param);
|
||
|
break;
|
||
|
|
||
|
case OT_PT_H264:
|
||
|
ret = sample_comm_venc_h264_param_init(chn_attr, chn_param);
|
||
|
break;
|
||
|
|
||
|
case OT_PT_MJPEG:
|
||
|
ret = sample_comm_venc_mjpeg_param_init(chn_attr, chn_param);
|
||
|
break;
|
||
|
|
||
|
case OT_PT_JPEG:
|
||
|
ret = sample_comm_venc_jpeg_param_init(chn_attr);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
sample_print("can't support this type (%d) in this version!\n", type);
|
||
|
return OT_ERR_VENC_NOT_SUPPORT;
|
||
|
}
|
||
|
|
||
|
sample_comm_venc_set_gop_attr(type, chn_attr, gop_attr);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_create(ot_venc_chn venc_chn, struct_comm_venc_chn_param *chn_param)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ot_venc_chn_attr venc_chn_attr;
|
||
|
ot_enum_pic_size size = chn_param->size;
|
||
|
|
||
|
chn_param->frame_rate = 30; /* 30 is a number */
|
||
|
chn_param->gop = 30; /* 30 is a number */
|
||
|
|
||
|
if (libapi_comm_sys_get_pic_size(size, &chn_param->venc_size) != TD_SUCCESS) {
|
||
|
sample_print("get picture size failed!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* step 1: create venc channel */
|
||
|
if ((ret = sample_comm_venc_channel_param_init(chn_param, &venc_chn_attr)) != TD_SUCCESS) {
|
||
|
sample_print("venc_channel_param_init failed!\n");
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
if ((ret = ss_mpi_venc_create_chn(venc_chn, &venc_chn_attr)) != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_create_chn [%d] failed with %#x! ===\n", venc_chn, ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
if (chn_param->type == OT_PT_JPEG) {
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
if ((ret = sample_comm_venc_close_reencode(venc_chn)) != TD_SUCCESS) {
|
||
|
ss_mpi_venc_destroy_chn(venc_chn);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* function : start venc stream mode
|
||
|
* note : rate control parameter need adjust, according your case.
|
||
|
*/
|
||
|
td_s32 sample_comm_venc_start(ot_venc_chn venc_chn, struct_comm_venc_chn_param *chn_param)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ot_venc_start_param start_param;
|
||
|
|
||
|
/* step 1: create encode chnl */
|
||
|
if ((ret = sample_comm_venc_create(venc_chn, chn_param)) != TD_SUCCESS) {
|
||
|
sample_print("sample_comm_venc_create failed with%#x! \n", ret);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
/* step 2: start recv venc pictures */
|
||
|
start_param.recv_pic_num = -1;
|
||
|
if ((ret = ss_mpi_venc_start_chn(venc_chn, &start_param)) != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_start_recv_pic failed with%#x! \n", ret);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* function : stop venc (stream mode-- H264, MJPEG) */
|
||
|
td_s32 sample_comm_venc_stop(ot_venc_chn venc_chn)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
|
||
|
/* stop venc chn */
|
||
|
ret = ss_mpi_venc_stop_chn(venc_chn);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_stop_chn vechn[%d] failed with %#x!\n", venc_chn, ret);
|
||
|
}
|
||
|
|
||
|
/* distroy venc channel */
|
||
|
ret = ss_mpi_venc_destroy_chn(venc_chn);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_destroy_chn vechn[%d] failed with %#x!\n", venc_chn, ret);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* start snap */
|
||
|
td_s32 sample_comm_venc_snap_start(ot_venc_chn venc_chn, ot_size *size, td_bool support_dcf)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ot_venc_chn_attr venc_chn_attr;
|
||
|
ot_venc_start_param start_param;
|
||
|
|
||
|
/* step 1: create venc channel */
|
||
|
venc_chn_attr.venc_attr.type = OT_PT_JPEG;
|
||
|
venc_chn_attr.venc_attr.max_pic_width = size->width;
|
||
|
venc_chn_attr.venc_attr.max_pic_height = size->height;
|
||
|
venc_chn_attr.venc_attr.pic_width = size->width;
|
||
|
venc_chn_attr.venc_attr.pic_height = size->height;
|
||
|
venc_chn_attr.venc_attr.buf_size = size->width * size->height * 2; /* 2 is a number */
|
||
|
venc_chn_attr.venc_attr.is_by_frame = TD_TRUE; /* get stream mode is field mode or frame mode */
|
||
|
venc_chn_attr.venc_attr.profile = 0;
|
||
|
venc_chn_attr.venc_attr.jpeg_attr.dcf_en = support_dcf;
|
||
|
venc_chn_attr.venc_attr.jpeg_attr.mpf_cfg.large_thumbnail_num = 0;
|
||
|
venc_chn_attr.venc_attr.jpeg_attr.recv_mode = OT_VENC_PIC_RECV_SINGLE;
|
||
|
|
||
|
ret = ss_mpi_venc_create_chn(venc_chn, &venc_chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_create_chn [%d] failed with %#x!\n", venc_chn, ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
ret = ss_mpi_venc_set_jpeg_enc_mode(venc_chn, OT_VENC_JPEG_ENC_SNAP);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_set_jpeg_enc_mode faild with%#x!\n", ret);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
start_param.recv_pic_num = -1;
|
||
|
ret = ss_mpi_venc_start_chn(venc_chn, &start_param);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("mpi_venc_start_chn faild with%#x!\n", ret);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* start photo */
|
||
|
td_s32 sample_comm_venc_photo_start(ot_venc_chn venc_chn, ot_size *size, td_bool support_dcf)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ot_venc_chn_attr venc_chn_attr;
|
||
|
ot_venc_start_param start_param;
|
||
|
|
||
|
/* step 1: create venc channel */
|
||
|
venc_chn_attr.venc_attr.type = OT_PT_JPEG;
|
||
|
venc_chn_attr.venc_attr.max_pic_width = size->width;
|
||
|
venc_chn_attr.venc_attr.max_pic_height = size->height;
|
||
|
venc_chn_attr.venc_attr.pic_width = size->width;
|
||
|
venc_chn_attr.venc_attr.pic_height = size->height;
|
||
|
venc_chn_attr.venc_attr.buf_size = size->width * size->height * 2; /* 2 is a number */
|
||
|
venc_chn_attr.venc_attr.is_by_frame = TD_TRUE; /* get stream mode is field mode or frame mode */
|
||
|
venc_chn_attr.venc_attr.profile = 0;
|
||
|
venc_chn_attr.venc_attr.jpeg_attr.dcf_en = support_dcf;
|
||
|
venc_chn_attr.venc_attr.jpeg_attr.mpf_cfg.large_thumbnail_num = 0;
|
||
|
venc_chn_attr.venc_attr.jpeg_attr.recv_mode = OT_VENC_PIC_RECV_SINGLE;
|
||
|
|
||
|
ret = ss_mpi_venc_create_chn(venc_chn, &venc_chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_create_chn [%d] failed with %#x!\n", venc_chn, ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
start_param.recv_pic_num = -1;
|
||
|
ret = ss_mpi_venc_start_chn(venc_chn, &start_param);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("mpi_venc_start_chn faild with%#x!\n", ret);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* stop snap */
|
||
|
td_s32 sample_comm_venc_snap_stop(ot_venc_chn venc_chn)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ret = ss_mpi_venc_stop_chn(venc_chn);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_stop_chn vechn[%d] failed with %#x!\n", venc_chn, ret);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
ret = ss_mpi_venc_destroy_chn(venc_chn);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_destroy_chn vechn[%d] failed with %#x!\n", venc_chn, ret);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_save_snap_stream(ot_venc_stream stream, td_bool save_jpg, td_bool save_thm)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
char stream_file[FILE_NAME_LEN] = {0};
|
||
|
FILE *file = TD_NULL;
|
||
|
td_s32 fd = -1;
|
||
|
|
||
|
if (snprintf_s(stream_file, FILE_NAME_LEN, FILE_NAME_LEN - 1, "snap_%d.jpg", g_snap_cnt) < 0) {
|
||
|
free(stream.pack);
|
||
|
stream.pack = NULL;
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
fd = open(stream_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||
|
if (fd < 0) {
|
||
|
sample_print("open file err\n");
|
||
|
free(stream.pack);
|
||
|
stream.pack = NULL;
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
file = fdopen(fd, "wb");
|
||
|
if (file == NULL) {
|
||
|
sample_print("fdopen err\n");
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
ret = sample_comm_venc_save_stream(file, &stream);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("save snap picture failed!\n");
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
if (save_thm) {
|
||
|
char file_dcf[FILE_NAME_LEN] = {0};
|
||
|
if (snprintf_s(file_dcf, FILE_NAME_LEN, FILE_NAME_LEN - 1, "snap_thm_%d.jpg", g_snap_cnt) < 0) {
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
ret = sample_comm_venc_get_dcf_info(stream_file, FILE_NAME_LEN, file_dcf, FILE_NAME_LEN);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("save thm picture failed!\n");
|
||
|
goto error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
(td_void)fclose(file);
|
||
|
file = TD_NULL;
|
||
|
g_snap_cnt++;
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
|
||
|
error:
|
||
|
free(stream.pack);
|
||
|
stream.pack = NULL;
|
||
|
|
||
|
(td_void)fclose(file);
|
||
|
file = TD_NULL;
|
||
|
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_get_snap_stream(ot_venc_chn venc_chn, td_bool save_jpg, td_bool save_thm)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ot_venc_chn_status stat;
|
||
|
ot_venc_stream stream;
|
||
|
|
||
|
ret = ss_mpi_venc_query_status(venc_chn, &stat);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("query_status failed with %#x!\n", ret);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (stat.cur_packs == 0) {
|
||
|
sample_print("NOTE: Current frame is NULL!\n");
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
stream.pack = (ot_venc_pack *)malloc(sizeof(ot_venc_pack) * stat.cur_packs);
|
||
|
if (stream.pack == NULL) {
|
||
|
sample_print("malloc memory failed!\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
stream.pack_cnt = stat.cur_packs;
|
||
|
ret = ss_mpi_venc_get_stream(venc_chn, &stream, -1);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("get_stream failed with %#x!\n", ret);
|
||
|
free(stream.pack);
|
||
|
stream.pack = NULL;
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
if (save_jpg || save_thm) {
|
||
|
ret = sample_comm_save_snap_stream(stream, save_jpg, save_thm);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("save_snap_stream failed!\n");
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ret = ss_mpi_venc_release_stream(venc_chn, &stream);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("release_stream failed with %#x!\n", ret);
|
||
|
|
||
|
free(stream.pack);
|
||
|
stream.pack = NULL;
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
free(stream.pack);
|
||
|
stream.pack = NULL;
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
* funciton : snap process
|
||
|
******************************************************************************/
|
||
|
td_s32 sample_comm_venc_snap_process(ot_venc_chn venc_chn, td_u32 snap_cnt, td_bool save_jpg, td_bool save_thm)
|
||
|
{
|
||
|
struct timeval timeout_val;
|
||
|
fd_set read_fds;
|
||
|
td_s32 venc_fd;
|
||
|
td_s32 ret;
|
||
|
td_u32 i;
|
||
|
|
||
|
/******************************************
|
||
|
step 4: recv picture
|
||
|
******************************************/
|
||
|
venc_fd = ss_mpi_venc_get_fd(venc_chn);
|
||
|
if (venc_fd < 0) {
|
||
|
sample_print("venc_get_fd faild with%#x!\n", venc_fd);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < snap_cnt; i++) {
|
||
|
FD_ZERO(&read_fds);
|
||
|
FD_SET(venc_fd, &read_fds);
|
||
|
timeout_val.tv_sec = 10; // 10 : 10 seconds
|
||
|
timeout_val.tv_usec = 0;
|
||
|
ret = select(venc_fd + 1, &read_fds, NULL, NULL, &timeout_val);
|
||
|
if (ret < 0) {
|
||
|
sample_print("snap select failed!\n");
|
||
|
return TD_FAILURE;
|
||
|
} else if (ret == 0) {
|
||
|
sample_print("snap time out!\n");
|
||
|
return TD_FAILURE;
|
||
|
} else {
|
||
|
if (FD_ISSET(venc_fd, &read_fds)) {
|
||
|
check_return(sample_comm_get_snap_stream(venc_chn, save_jpg, save_thm), "get_snap_stream");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_save_jpeg(ot_venc_chn venc_chn, td_u32 snap_cnt)
|
||
|
{
|
||
|
struct timeval timeout_val;
|
||
|
fd_set read_fds;
|
||
|
td_s32 venc_fd;
|
||
|
td_s32 ret;
|
||
|
td_u32 i;
|
||
|
/******************************************
|
||
|
step: recv picture
|
||
|
******************************************/
|
||
|
venc_fd = ss_mpi_venc_get_fd(venc_chn);
|
||
|
if (venc_fd < 0) {
|
||
|
sample_print("venc_get_fd faild with%#x!\n", venc_fd);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
for (i = 0; i < snap_cnt; i++) {
|
||
|
FD_ZERO(&read_fds);
|
||
|
FD_SET(venc_fd, &read_fds);
|
||
|
timeout_val.tv_sec = 10; // 10 : 10 seconds
|
||
|
timeout_val.tv_usec = 0;
|
||
|
ret = select(venc_fd + 1, &read_fds, NULL, NULL, &timeout_val);
|
||
|
if (ret < 0) {
|
||
|
sample_print("snap select failed!\n");
|
||
|
return TD_FAILURE;
|
||
|
} else if (ret == 0) {
|
||
|
sample_print("snap time out!\n");
|
||
|
return TD_FAILURE;
|
||
|
} else {
|
||
|
if (FD_ISSET(venc_fd, &read_fds)) {
|
||
|
check_return(sample_comm_get_snap_stream(venc_chn, TD_TRUE, TD_FALSE), "get_snap_stream");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_alloc_qpmap_skipweight_memory(struct_venc_qpmap_sendframe_para *para,
|
||
|
sample_comm_venc_frame_proc_info *addr_info)
|
||
|
{
|
||
|
ot_venc_chn_attr venc_chn_attr;
|
||
|
td_u32 j;
|
||
|
td_s32 i, ret;
|
||
|
td_u8 *vir_addr = TD_NULL;
|
||
|
td_phys_addr_t phys_addr = 0;
|
||
|
|
||
|
for (i = 0; (i < para->cnt) && (i < OT_VENC_MAX_CHN_NUM); i++) {
|
||
|
ss_mpi_venc_get_chn_attr(para->venc_chn[i], &venc_chn_attr);
|
||
|
|
||
|
addr_info->qpmap_size[i] = ot_venc_get_qpmap_size(venc_chn_attr.venc_attr.type,
|
||
|
para->size[i].width, para->size[i].height);
|
||
|
addr_info->skip_weight_size[i] =
|
||
|
ot_venc_get_skip_weight_size(venc_chn_attr.venc_attr.type, para->size[i].width, para->size[i].height);
|
||
|
|
||
|
/* alloc qpmap memory */
|
||
|
ret = ss_mpi_sys_mmz_alloc((td_phys_addr_t *)&phys_addr, (td_void **)&vir_addr, TD_NULL, TD_NULL,
|
||
|
addr_info->qpmap_size[i] * QPMAP_BUF_NUM);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_sys_mmz_alloc err:0x%x", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
for (j = 0; (i < VENC_QPMAP_MAX_CHN) && (j < QPMAP_BUF_NUM); j++) {
|
||
|
if ((j > 0) && (addr_info->qpmap_size[i] > (UINT_MAX / j))) {
|
||
|
sample_print("(j * addr_info->qpmap_size[%d]) upper limit of the multiplie\n", i);
|
||
|
ss_mpi_sys_mmz_free(phys_addr, vir_addr);
|
||
|
return TD_FAILURE;
|
||
|
} else {
|
||
|
addr_info->qpmap_phys_addr[i][j] = (td_phys_addr_t)(phys_addr + j * addr_info->qpmap_size[i]);
|
||
|
addr_info->qpmap_vir_addr[i][j] = vir_addr + j * addr_info->qpmap_size[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* alloc skipWeight memory */
|
||
|
ret = ss_mpi_sys_mmz_alloc((td_phys_addr_t *)&phys_addr, (td_void **)&vir_addr, TD_NULL, TD_NULL,
|
||
|
addr_info->skip_weight_size[i] * QPMAP_BUF_NUM);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_sys_mmz_alloc err:0x%x", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
for (j = 0; (i < VENC_QPMAP_MAX_CHN) && (j < QPMAP_BUF_NUM); j++) {
|
||
|
if ((j > 0) && (addr_info->skip_weight_size[i] > (UINT_MAX / j))) {
|
||
|
sample_print("(j * addr_info->skip_weight_size[%d]) upper limit of the multiplie\n", i);
|
||
|
ss_mpi_sys_mmz_free(phys_addr, vir_addr);
|
||
|
return TD_FAILURE;
|
||
|
} else {
|
||
|
addr_info->skip_weight_phys_addr[i][j] =
|
||
|
(td_phys_addr_t)(phys_addr + j * addr_info->skip_weight_size[i]);
|
||
|
addr_info->skip_weight_vir_addr[i][j] = vir_addr + j * addr_info->skip_weight_size[i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_venc_vir_addr_temp(sample_comm_venc_frame_proc_info *addr_info, td_u32 i, td_u32 frame_id)
|
||
|
{
|
||
|
td_u32 j;
|
||
|
td_u8 *vir_addr_temp = TD_NULL;
|
||
|
|
||
|
vir_addr_temp = (td_u8 *)addr_info->qpmap_vir_addr[i][frame_id];
|
||
|
for (j = 0; j < addr_info->qpmap_size[i]; j++) {
|
||
|
*vir_addr_temp = 0x5E; // [7]:skip flag; [6]:QpType Flag; [5:0]:Qp value ==> Set absolute qp = 30
|
||
|
vir_addr_temp++;
|
||
|
}
|
||
|
|
||
|
vir_addr_temp = (td_u8 *)addr_info->skip_weight_vir_addr[i][frame_id];
|
||
|
for (j = 0; j < addr_info->skip_weight_size[i]; j++) {
|
||
|
*vir_addr_temp = 0x66; // inter block must be skip
|
||
|
vir_addr_temp++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static td_s32 sample_comm_qpmap_send_frame_ex(struct_venc_qpmap_sendframe_para *para,
|
||
|
ot_venc_user_frame_info *frame_info, ot_video_frame_info *video_frame, td_s32 index)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
|
||
|
ret = ss_mpi_venc_send_frame_ex(para->venc_chn[index], frame_info, -1);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_send_frame_ex err:0x%x\n", ret);
|
||
|
|
||
|
ret = ss_mpi_vpss_release_chn_frame(para->vpss_grp, para->vpss_chn[index], video_frame);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_release_chn_frame err:0x%x", ret);
|
||
|
return SAMPLE_RETURN_GOTO;
|
||
|
}
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_qpmap_send_frame_start(struct_venc_qpmap_sendframe_para *para,
|
||
|
sample_comm_venc_frame_proc_info *addr_info)
|
||
|
{
|
||
|
td_u32 frame_id = 0;
|
||
|
td_s32 i, ret;
|
||
|
ot_venc_user_frame_info frame_info[VENC_QPMAP_MAX_CHN][QPMAP_BUF_NUM] = { 0 };
|
||
|
|
||
|
while (para->thread_start == TD_TRUE) {
|
||
|
for (i = 0; (i < para->cnt) && (i < VENC_QPMAP_MAX_CHN); i++) {
|
||
|
ot_video_frame_info *video_frame = &frame_info[i][frame_id].user_frame;
|
||
|
ret = ss_mpi_vpss_get_chn_frame(para->vpss_grp, para->vpss_chn[i],
|
||
|
video_frame, 1000); /* 1000 is a number */
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("OT_MPI_VPSS_GetChnFrame err:0x%x\n", ret);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
sample_comm_venc_vir_addr_temp(addr_info, i, frame_id);
|
||
|
|
||
|
frame_info[i][frame_id].user_rc_info.skip_weight_valid = 1;
|
||
|
frame_info[i][frame_id].user_rc_info.skip_weight_phys_addr = addr_info->skip_weight_phys_addr[i][frame_id];
|
||
|
frame_info[i][frame_id].user_rc_info.qpmap_valid = 1;
|
||
|
frame_info[i][frame_id].user_rc_info.qpmap_phys_addr = addr_info->qpmap_phys_addr[i][frame_id];
|
||
|
frame_info[i][frame_id].user_rc_info.blk_start_qp = 30; /* 30 is a number */
|
||
|
frame_info[i][frame_id].user_rc_info.frame_type = OT_VENC_FRAME_TYPE_NONE;
|
||
|
|
||
|
ret = sample_comm_qpmap_send_frame_ex(para, &frame_info[i][frame_id], video_frame, i);
|
||
|
if (ret == SAMPLE_RETURN_BREAK) {
|
||
|
break;
|
||
|
} else if (ret == SAMPLE_RETURN_GOTO) {
|
||
|
return SAMPLE_RETURN_GOTO;
|
||
|
}
|
||
|
|
||
|
ret = ss_mpi_vpss_release_chn_frame(para->vpss_grp, para->vpss_chn[i], video_frame);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_release_chn_frame err:0x%x", ret);
|
||
|
return SAMPLE_RETURN_GOTO;
|
||
|
}
|
||
|
|
||
|
frame_id++;
|
||
|
if (frame_id >= QPMAP_BUF_NUM) {
|
||
|
frame_id = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
td_void *sample_comm_qpmap_send_frame_proc(td_void *p)
|
||
|
{
|
||
|
td_s32 i, ret;
|
||
|
struct_venc_qpmap_sendframe_para *para = TD_NULL;
|
||
|
sample_comm_venc_frame_proc_info addr_info = { 0 };
|
||
|
ot_vpss_chn_attr vpss_chn_attr;
|
||
|
|
||
|
para = (struct_venc_qpmap_sendframe_para *)p;
|
||
|
|
||
|
if (para->cnt > VENC_QPMAP_MAX_CHN) {
|
||
|
sample_print("Current func'sample_comm_qpmap_send_frame_proc' not support Venc channal num(%d) > %d\n",
|
||
|
para->cnt, VENC_QPMAP_MAX_CHN);
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
if (sample_comm_alloc_qpmap_skipweight_memory(para, &addr_info) != TD_SUCCESS) {
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* set vpss buffer depth */
|
||
|
for (i = 0; (i < para->cnt) && (i < OT_VPSS_MAX_PHYS_CHN_NUM); i++) {
|
||
|
ret = ss_mpi_vpss_get_chn_attr(para->vpss_grp, para->vpss_chn[i], &vpss_chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_get_chn_attr err:0x%x", ret);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
vpss_chn_attr.depth = 3; /* 3 is a number */
|
||
|
ret = ss_mpi_vpss_set_chn_attr(para->vpss_grp, para->vpss_chn[i], &vpss_chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_set_chn_attr err:0x%x", ret);
|
||
|
goto error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (sample_comm_qpmap_send_frame_start(para, &addr_info) != TD_SUCCESS) {
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
error:
|
||
|
for (i = 0; (i < para->cnt) && (i < VENC_QPMAP_MAX_CHN); i++) {
|
||
|
if (addr_info.qpmap_phys_addr[i][0] != 0) {
|
||
|
ret = ss_mpi_sys_mmz_free(addr_info.qpmap_phys_addr[i][0], addr_info.qpmap_vir_addr[i][0]);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_sys_mmz_free err:0x%x", ret);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (addr_info.skip_weight_phys_addr[i][0] != 0) {
|
||
|
ret = ss_mpi_sys_mmz_free(addr_info.skip_weight_phys_addr[i][0], addr_info.skip_weight_vir_addr[i][0]);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_sys_mmz_free err:0x%x", ret);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_qpmap_send_frame(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn[], ot_venc_chn venc_chn[],
|
||
|
td_s32 cnt, ot_size size[])
|
||
|
{
|
||
|
td_s32 i;
|
||
|
|
||
|
g_qpmap_send_frame_para.thread_start = TD_TRUE;
|
||
|
g_qpmap_send_frame_para.vpss_grp = vpss_grp;
|
||
|
g_qpmap_send_frame_para.cnt = cnt;
|
||
|
|
||
|
for (i = 0; (i < cnt) && (i < OT_VENC_MAX_CHN_NUM) && (i < OT_VPSS_MAX_PHYS_CHN_NUM); i++) {
|
||
|
g_qpmap_send_frame_para.venc_chn[i] = venc_chn[i];
|
||
|
g_qpmap_send_frame_para.vpss_chn[i] = vpss_chn[i];
|
||
|
g_qpmap_send_frame_para.size[i] = size[i];
|
||
|
}
|
||
|
|
||
|
return pthread_create(&g_venc_qpmap_pid, 0, sample_comm_qpmap_send_frame_proc, (td_void *)&g_qpmap_send_frame_para);
|
||
|
}
|
||
|
|
||
|
#define SAMPLE_VENC_BLOCK_WIDTH 16
|
||
|
#define SAMPLE_VENC_BLOCK_HEIGHT 16
|
||
|
#define SAMPLE_VENC_ONE_BYTE_BLOCKS 4
|
||
|
#define SAMPLE_VENC_ONE_BLOCK_BITS 2
|
||
|
#define SAMPLE_VENC_MAX_JPEG_ROI_LEVEL 3
|
||
|
|
||
|
static td_void sample_venc_set_2bits(td_u8 *wp, td_u32 idx, td_u32 value)
|
||
|
{
|
||
|
td_u8 tmp1, tmp2;
|
||
|
tmp1 = *wp;
|
||
|
|
||
|
tmp2 = ~(3 << (idx * SAMPLE_VENC_ONE_BLOCK_BITS)); // 3: 0b11
|
||
|
tmp1 &= tmp2;
|
||
|
tmp2 = value << (idx * SAMPLE_VENC_ONE_BLOCK_BITS);
|
||
|
tmp1 |= tmp2;
|
||
|
*wp = tmp1;
|
||
|
}
|
||
|
|
||
|
static td_void sample_venc_process_jpeg_roi_head(td_u8 **wp, td_u32 start_idx, td_u32 fill_block, td_u32 value)
|
||
|
{
|
||
|
td_u32 i;
|
||
|
|
||
|
for (i = 0; i < fill_block; i++) {
|
||
|
sample_venc_set_2bits(*wp, start_idx + i, value);
|
||
|
}
|
||
|
|
||
|
if (i != 0) {
|
||
|
*wp = *wp + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static td_void sample_venc_process_jpeg_roi_middle(td_u8 **wp, td_u32 write_byte, td_u32 value)
|
||
|
{
|
||
|
td_s32 i;
|
||
|
if (write_byte != 0) {
|
||
|
for (i = 0; i < (SAMPLE_VENC_ONE_BYTE_BLOCKS - 1); i++) {
|
||
|
value |= value << SAMPLE_VENC_ONE_BLOCK_BITS;
|
||
|
}
|
||
|
if (memset_s(*wp, write_byte, value, write_byte) != EOK) {
|
||
|
printf("call memset_s error\n");
|
||
|
}
|
||
|
*wp = *wp + write_byte;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static td_void sample_venc_process_jpeg_roi_tail(td_u8 **wp, td_u32 fill_block, td_u32 value)
|
||
|
{
|
||
|
td_u32 i;
|
||
|
|
||
|
for (i = 0; i < fill_block; i++) {
|
||
|
sample_venc_set_2bits(*wp, i, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
td_void sample_venc_process_jpeg_roi(td_void *virt_addr, ot_rect *rect, td_u32 roi_level, td_u32 stride)
|
||
|
{
|
||
|
td_u32 i, level, start_block, start_byte, start_supple_idx, start_supple_block, start_block_height;
|
||
|
td_u32 start_x, start_y, write_block, write_resi_block, write_byte, write_tail_block, write_block_height;
|
||
|
|
||
|
start_x = rect->x;
|
||
|
start_block = start_x / SAMPLE_VENC_BLOCK_WIDTH;
|
||
|
start_byte = start_block / SAMPLE_VENC_ONE_BYTE_BLOCKS;
|
||
|
start_supple_idx = start_block % SAMPLE_VENC_ONE_BYTE_BLOCKS;
|
||
|
start_supple_block = (start_supple_idx == 0) ? 0 : (SAMPLE_VENC_ONE_BYTE_BLOCKS - start_supple_idx);
|
||
|
|
||
|
write_block = rect->width / SAMPLE_VENC_BLOCK_WIDTH;
|
||
|
start_supple_block = (start_supple_block < write_block) ? start_supple_block : write_block;
|
||
|
write_resi_block = write_block - start_supple_block;
|
||
|
write_byte = write_resi_block / SAMPLE_VENC_ONE_BYTE_BLOCKS;
|
||
|
write_tail_block = write_resi_block % SAMPLE_VENC_ONE_BYTE_BLOCKS;
|
||
|
|
||
|
start_y = rect->y;
|
||
|
start_block_height = start_y / SAMPLE_VENC_BLOCK_HEIGHT;
|
||
|
write_block_height = rect->height / SAMPLE_VENC_BLOCK_HEIGHT;
|
||
|
level = roi_level;
|
||
|
|
||
|
for (i = 0; i < write_block_height; i++) {
|
||
|
td_u8 *wp = (td_u8 *)virt_addr + (start_block_height + i) * stride + start_byte;
|
||
|
sample_venc_process_jpeg_roi_head(&wp, start_supple_idx, start_supple_block, level);
|
||
|
sample_venc_process_jpeg_roi_middle(&wp, write_byte, level);
|
||
|
sample_venc_process_jpeg_roi_tail(&wp, write_tail_block, level);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#define SAMPLE_VENC_ROIMAP_MAX_CHN 2
|
||
|
|
||
|
static td_s32 sample_comm_venc_send_frame_ex(struct_venc_roimap_frame_para *para, ot_venc_user_frame_info *frame_info,
|
||
|
ot_video_frame_info *video_frame, td_s32 index, td_s32 venc_roimap_max_chn)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ot_unused(venc_roimap_max_chn);
|
||
|
|
||
|
ret = ss_mpi_venc_send_frame_ex(para->venc_chn[index], &frame_info[index], -1);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_send_frame_ex err: 0x%x\n", ret);
|
||
|
|
||
|
ret = ss_mpi_vpss_release_chn_frame(para->vpss_grp, para->vpss_chn[index], video_frame);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_release_chn_frame err: 0x%x", ret);
|
||
|
return SAMPLE_RETURN_GOTO;
|
||
|
}
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_venc_send_roimap_frame_start(struct_venc_roimap_frame_para *para,
|
||
|
td_phys_addr_t *roimap_phys_addr)
|
||
|
{
|
||
|
td_s32 i, ret;
|
||
|
ot_venc_user_frame_info frame_info[SAMPLE_VENC_ROIMAP_MAX_CHN] = {0};
|
||
|
|
||
|
while (para->thread_start == TD_TRUE) {
|
||
|
for (i = 0; (i < para->cnt) && (i < SAMPLE_VENC_ROIMAP_MAX_CHN) &&
|
||
|
(i < OT_VPSS_MAX_PHYS_CHN_NUM) && (i < OT_VENC_MAX_CHN_NUM); i++) {
|
||
|
ot_video_frame_info *video_frame = &frame_info[i].user_frame;
|
||
|
ret = ss_mpi_vpss_get_chn_frame(para->vpss_grp, para->vpss_chn[i],
|
||
|
video_frame, 1000); /* 1000 is a number */
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_get_chn_frame err: 0x%x\n", ret);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
frame_info[i].user_roimap.valid = TD_TRUE;
|
||
|
frame_info[i].user_roimap.phys_addr = roimap_phys_addr[i];
|
||
|
|
||
|
ret = sample_comm_venc_send_frame_ex(para, frame_info, video_frame, i, SAMPLE_VENC_ROIMAP_MAX_CHN);
|
||
|
if (ret == SAMPLE_RETURN_BREAK) {
|
||
|
break;
|
||
|
} else if (ret == SAMPLE_RETURN_GOTO) {
|
||
|
return SAMPLE_RETURN_GOTO;
|
||
|
}
|
||
|
|
||
|
ret = ss_mpi_vpss_release_chn_frame(para->vpss_grp, para->vpss_chn[i], video_frame);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_release_chn_frame err: 0x%x", ret);
|
||
|
return SAMPLE_RETURN_GOTO;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_set_vpss_buffer_depth(struct_venc_roimap_frame_para *para, td_phys_addr_t *roimap_phys_addr)
|
||
|
{
|
||
|
td_s32 i, ret;
|
||
|
ot_vpss_chn_attr vpss_chn_attr;
|
||
|
|
||
|
for (i = 0; (i < para->cnt) && (i < OT_VPSS_MAX_PHYS_CHN_NUM); i++) {
|
||
|
ret = ss_mpi_vpss_get_chn_attr(para->vpss_grp, para->vpss_chn[i], &vpss_chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_get_chn_attr err: 0x%x", ret);
|
||
|
return SAMPLE_RETURN_GOTO;
|
||
|
}
|
||
|
|
||
|
vpss_chn_attr.depth = 3; // 3 : depth
|
||
|
ret = ss_mpi_vpss_set_chn_attr(para->vpss_grp, para->vpss_chn[i], &vpss_chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_set_chn_attr err: 0x%x", ret);
|
||
|
return SAMPLE_RETURN_GOTO;
|
||
|
}
|
||
|
}
|
||
|
ret = sample_comm_venc_send_roimap_frame_start(para, roimap_phys_addr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
return SAMPLE_RETURN_GOTO;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
td_void *sample_comm_send_roimap_frame_proc(td_void *p)
|
||
|
{
|
||
|
td_s32 i, j, ret;
|
||
|
td_u8 init_level = 2;
|
||
|
|
||
|
td_u32 roimap_size[SAMPLE_VENC_ROIMAP_MAX_CHN], roimap_stride[SAMPLE_VENC_ROIMAP_MAX_CHN];
|
||
|
td_phys_addr_t roimap_phys_addr[SAMPLE_VENC_ROIMAP_MAX_CHN] = {0};
|
||
|
td_void *roimap_virt_addr[SAMPLE_VENC_ROIMAP_MAX_CHN] = {0};
|
||
|
|
||
|
td_u8 *virt_addr = TD_NULL;
|
||
|
td_phys_addr_t phys_addr = TD_NULL;
|
||
|
|
||
|
ot_venc_chn_attr venc_chn_attr;
|
||
|
|
||
|
struct_venc_roimap_frame_para *para = (struct_venc_roimap_frame_para *)p;
|
||
|
|
||
|
if (para->cnt > SAMPLE_VENC_ROIMAP_MAX_CHN) {
|
||
|
sample_print("Current not support venc channal num(%d) > %d\n", para->cnt, SAMPLE_VENC_ROIMAP_MAX_CHN);
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
for (i = 0; (i < para->cnt) && (i < OT_VENC_MAX_CHN_NUM) && (i < SAMPLE_VENC_ROIMAP_MAX_CHN); i++) {
|
||
|
ss_mpi_venc_get_chn_attr(para->venc_chn[i], &venc_chn_attr);
|
||
|
|
||
|
roimap_size[i] =
|
||
|
ot_venc_get_roimap_size(venc_chn_attr.venc_attr.type, para->size[i].width, para->size[i].width);
|
||
|
roimap_stride[i] = ot_venc_get_roimap_stride(venc_chn_attr.venc_attr.type, para->size[i].width);
|
||
|
|
||
|
/* alloc roimap memory */
|
||
|
ret = ss_mpi_sys_mmz_alloc(&phys_addr, (td_void **)&virt_addr, TD_NULL, TD_NULL, roimap_size[i]);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_sys_mmz_alloc err: 0x%x", ret);
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
roimap_phys_addr[i] = phys_addr;
|
||
|
roimap_virt_addr[i] = virt_addr;
|
||
|
|
||
|
for (j = 0; j < (4 - 1); j++) { /* 4 is a number */
|
||
|
init_level |= (init_level << 4); /* 4 is a number */
|
||
|
}
|
||
|
if (memset_s(roimap_virt_addr[i], roimap_size[i], init_level, roimap_size[i]) != EOK) {
|
||
|
printf("call memset_s error\n");
|
||
|
}
|
||
|
sample_venc_process_jpeg_roi(roimap_virt_addr[i], ¶->roi_attr[i].rect, para->roi_attr[i].level,
|
||
|
roimap_stride[i]);
|
||
|
}
|
||
|
|
||
|
/* set vpss buffer depth */
|
||
|
if (sample_comm_set_vpss_buffer_depth(para, roimap_phys_addr) != TD_SUCCESS) {
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
error:
|
||
|
for (i = 0; (i < para->cnt) && (i < SAMPLE_VENC_ROIMAP_MAX_CHN); i++) {
|
||
|
if (roimap_phys_addr[i] != 0) {
|
||
|
ret = ss_mpi_sys_mmz_free(roimap_phys_addr[i], roimap_virt_addr[i]);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_sys_mmz_free err: 0x%x", ret);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_send_roimap_frame(ot_vpss_grp vpss_grp, struct_venc_roimap_chn_info roimap_chn_info,
|
||
|
ot_size size[], ot_venc_jpeg_roi_attr roi_attr[])
|
||
|
{
|
||
|
td_s32 i;
|
||
|
|
||
|
g_roimap_frame_param.thread_start = TD_TRUE;
|
||
|
g_roimap_frame_param.vpss_grp = vpss_grp;
|
||
|
g_roimap_frame_param.cnt = roimap_chn_info.cnt;
|
||
|
|
||
|
for (i = 0; (i < roimap_chn_info.cnt) && (i < OT_VENC_MAX_CHN_NUM) && (i < OT_VPSS_MAX_PHYS_CHN_NUM); i++) {
|
||
|
g_roimap_frame_param.venc_chn[i] = roimap_chn_info.venc_chn[i];
|
||
|
g_roimap_frame_param.vpss_chn[i] = roimap_chn_info.vpss_chn[i];
|
||
|
g_roimap_frame_param.size[i] = size[i];
|
||
|
g_roimap_frame_param.roi_attr[i] = roi_attr[i];
|
||
|
}
|
||
|
|
||
|
return pthread_create(&g_venc_roimap_pid, 0, sample_comm_send_roimap_frame_proc, (td_void *)&g_roimap_frame_param);
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_set_file_name(td_s32 index, ot_venc_chn venc_chn,
|
||
|
sample_comm_venc_stream_proc_info *stream_proc_info)
|
||
|
{
|
||
|
if (snprintf_s(stream_proc_info->file_name[index], FILE_NAME_LEN, FILE_NAME_LEN - 1, "./") < 0) {
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
|
||
|
if (realpath(stream_proc_info->file_name[index], stream_proc_info->real_file_name[index]) == TD_NULL) {
|
||
|
sample_print("chn[%d] stream file path error\n", venc_chn);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
|
||
|
if (snprintf_s(stream_proc_info->real_file_name[index], FILE_NAME_LEN, FILE_NAME_LEN - 1,
|
||
|
"stream_chn%d%s", index, stream_proc_info->file_postfix) < 0) {
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_set_name_save_stream(sample_comm_venc_stream_proc_info *stream_proc_info,
|
||
|
ot_venc_stream_buf_info *stream_buf_info, ot_payload_type *payload_type,
|
||
|
struct_venc_getstream_para *para, td_s32 venc_max_chn)
|
||
|
{
|
||
|
td_s32 i, ret, fd;
|
||
|
ot_venc_chn_attr venc_chn_attr;
|
||
|
ot_unused(venc_max_chn);
|
||
|
|
||
|
for (i = 0; (i < stream_proc_info->chn_total) && (i < OT_VENC_MAX_CHN_NUM); i++) {
|
||
|
/* decide the stream file name, and open file to save stream */
|
||
|
ot_venc_chn venc_chn = para->venc_chn[i];
|
||
|
ret = ss_mpi_venc_get_chn_attr(venc_chn, &venc_chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_get_chn_attr chn[%d] failed with %#x!\n", venc_chn, ret);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
payload_type[i] = venc_chn_attr.venc_attr.type;
|
||
|
|
||
|
ret = sample_comm_venc_get_file_postfix(payload_type[i], stream_proc_info->file_postfix,
|
||
|
sizeof(stream_proc_info->file_postfix));
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("sample_comm_venc_get_file_postfix [%d] failed with %#x!\n",
|
||
|
venc_chn_attr.venc_attr.type, ret);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
|
||
|
if (payload_type[i] != OT_PT_JPEG) {
|
||
|
ret = sample_comm_set_file_name(i, venc_chn, stream_proc_info);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
stream_proc_info->file[i] = fopen(stream_proc_info->real_file_name[i], "wb");
|
||
|
if (!stream_proc_info->file[i]) {
|
||
|
sample_print("open file[%s] failed!\n", stream_proc_info->real_file_name[i]);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
fd = fileno(stream_proc_info->file[i]);
|
||
|
fchmod(fd, S_IRUSR | S_IWUSR);
|
||
|
}
|
||
|
/* set venc fd. */
|
||
|
stream_proc_info->venc_fd[i] = ss_mpi_venc_get_fd(i);
|
||
|
if (stream_proc_info->venc_fd[i] < 0) {
|
||
|
sample_print("ss_mpi_venc_get_fd failed with %#x!\n", stream_proc_info->venc_fd[i]);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
|
||
|
if (stream_proc_info->maxfd <= stream_proc_info->venc_fd[i]) {
|
||
|
stream_proc_info->maxfd = stream_proc_info->venc_fd[i];
|
||
|
}
|
||
|
|
||
|
ret = ss_mpi_venc_get_stream_buf_info(i, &stream_buf_info[i]);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_get_stream_buf_info failed with %#x!\n", ret);
|
||
|
return SAMPLE_RETURN_FAILURE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static int32_t sample_heif_create(td_s32 index, const sample_comm_venc_stream_proc_info *stream_proc_info,
|
||
|
heif_handle *hdl)
|
||
|
{
|
||
|
// heif_config config;
|
||
|
// if (snprintf_s(config.file_desc.input.url, FILE_NAME_LEN, FILE_NAME_LEN - 1,
|
||
|
// "./stream_chn%d_%d%s", index, stream_proc_info->picture_cnt[index], ".heic") < 0) {
|
||
|
// return SAMPLE_RETURN_NULL;
|
||
|
// }
|
||
|
// config.file_desc.file_type = HEIF_FILE_TYPE_URL;
|
||
|
// config.config_type = HEIF_CONFIG_MUXER;
|
||
|
// config.muxer_config.is_grid = false;
|
||
|
// config.muxer_config.row_image_num = 1;
|
||
|
// config.muxer_config.column_image_num = 1;
|
||
|
// config.muxer_config.format_profile = HEIF_PROFILE_HEIC;
|
||
|
// return heif_create(hdl, &config);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_save_h265_to_heic(td_s32 index, const sample_comm_venc_stream_proc_info *stream_proc_info,
|
||
|
const ot_venc_stream *stream)
|
||
|
{
|
||
|
// td_u32 i;
|
||
|
// td_u32 total_len = 0;
|
||
|
// td_s32 has_key = 0;
|
||
|
// for (i = 0; i < stream->pack_cnt; i++) {
|
||
|
// if (stream->pack[i].data_type.h265_type == OT_VENC_H265_NALU_IDR_SLICE) {
|
||
|
// has_key = 1;
|
||
|
// }
|
||
|
// total_len += stream->pack[i].len - stream->pack[i].offset;
|
||
|
// }
|
||
|
// if (total_len > 0 && has_key == 1) {
|
||
|
// heif_handle handle = NULL;
|
||
|
// td_s32 ret = sample_heif_create(index, stream_proc_info, &handle);
|
||
|
// if (ret != 0) {
|
||
|
// sample_print("HeifCreate error ret:%d\n", ret);
|
||
|
// }
|
||
|
// td_u8 *data_buffer = (td_u8 *)malloc(total_len);
|
||
|
// if (data_buffer == NULL) {
|
||
|
// sample_print("malloc error\n");
|
||
|
// heif_destroy(handle);
|
||
|
// return SAMPLE_RETURN_NULL;
|
||
|
// }
|
||
|
// td_u32 write_len = 0;
|
||
|
// for (i = 0; i < stream->pack_cnt; i++) {
|
||
|
// if (memcpy_s(data_buffer + write_len, total_len - write_len,
|
||
|
// stream->pack[i].addr + stream->pack[i].offset, stream->pack[i].len - stream->pack[i].offset) != EOK) {
|
||
|
// sample_print("memcpy_s failed\n");
|
||
|
// }
|
||
|
// write_len += stream->pack[i].len;
|
||
|
// }
|
||
|
// heif_image_item item = {0};
|
||
|
// item.timestamp = -1;
|
||
|
// item.data = data_buffer;
|
||
|
// item.length = write_len;
|
||
|
// item.key_frame = true;
|
||
|
// ret = heif_write_master_image(handle, 0, &item, 1);
|
||
|
// if (data_buffer != NULL) {
|
||
|
// free(data_buffer);
|
||
|
// }
|
||
|
// heif_destroy(handle);
|
||
|
// return ret;
|
||
|
// }
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_save_frame_to_file(td_s32 index, sample_comm_venc_stream_proc_info *stream_proc_info,
|
||
|
ot_venc_stream *stream, ot_venc_stream_buf_info *stream_buf_info, ot_payload_type *payload_type)
|
||
|
{
|
||
|
td_s32 ret, fd;
|
||
|
if (payload_type[index] == OT_PT_JPEG) {
|
||
|
if (snprintf_s(stream_proc_info->file_name[index], FILE_NAME_LEN, FILE_NAME_LEN - 1, "./") < 0) {
|
||
|
free(stream->pack);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
if (realpath(stream_proc_info->file_name[index], stream_proc_info->real_file_name[index]) == TD_NULL) {
|
||
|
free(stream->pack);
|
||
|
sample_print("chn[%d] stream file path error\n", stream_proc_info->venc_chn);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
|
||
|
if (snprintf_s(stream_proc_info->real_file_name[index], FILE_NAME_LEN, FILE_NAME_LEN - 1,
|
||
|
"stream_chn%d_%d%s", index, stream_proc_info->picture_cnt[index], stream_proc_info->file_postfix) < 0) {
|
||
|
free(stream->pack);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
stream_proc_info->file[index] = fopen(stream_proc_info->real_file_name[index], "wb");
|
||
|
if (!stream_proc_info->file[index]) {
|
||
|
free(stream->pack);
|
||
|
sample_print("open file err!\n");
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
fd = fileno(stream_proc_info->file[index]);
|
||
|
fchmod(fd, S_IRUSR | S_IWUSR);
|
||
|
}
|
||
|
|
||
|
if (payload_type[index] == OT_PT_H265 && stream_proc_info->save_heif == TD_TRUE) {
|
||
|
// (td_void)sample_comm_save_h265_to_heic(index, stream_proc_info, stream);
|
||
|
}
|
||
|
#ifndef __LITEOS__
|
||
|
ot_unused(stream_buf_info);
|
||
|
ret = sample_comm_venc_save_stream(stream_proc_info->file[index], stream);
|
||
|
#else
|
||
|
ret = sample_comm_venc_save_stream_phys_addr(stream_proc_info->file[index], &stream_buf_info[index], stream);
|
||
|
#endif
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
free(stream->pack);
|
||
|
stream->pack = TD_NULL;
|
||
|
sample_print("save stream failed!\n");
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_get_stream_from_one_channl(sample_comm_venc_stream_proc_info *stream_proc_info,
|
||
|
td_s32 index, ot_venc_stream_buf_info *stream_buf_info, ot_payload_type *payload_type)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ot_venc_stream stream;
|
||
|
ot_venc_chn_status stat;
|
||
|
|
||
|
/* step 2.1 : query how many packs in one-frame stream. */
|
||
|
if (memset_s(&stream, sizeof(stream), 0, sizeof(stream)) != EOK) {
|
||
|
printf("call memset_s error\n");
|
||
|
}
|
||
|
|
||
|
ret = ss_mpi_venc_query_status(index, &stat);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_query_status chn[%d] failed with %#x!\n", index, ret);
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
|
||
|
if (stat.cur_packs == 0) {
|
||
|
sample_print("NOTE: current frame is TD_NULL!\n");
|
||
|
return SAMPLE_RETURN_CONTINUE;
|
||
|
}
|
||
|
/* step 2.3 : malloc corresponding number of pack nodes. */
|
||
|
stream.pack = (ot_venc_pack *)malloc(sizeof(ot_venc_pack) * stat.cur_packs);
|
||
|
if (stream.pack == TD_NULL) {
|
||
|
sample_print("malloc stream pack failed!\n");
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
|
||
|
/* step 2.4 : call mpi to get one-frame stream */
|
||
|
stream.pack_cnt = stat.cur_packs;
|
||
|
ret = ss_mpi_venc_get_stream(index, &stream, TD_TRUE);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
free(stream.pack);
|
||
|
stream.pack = TD_NULL;
|
||
|
sample_print("ss_mpi_venc_get_stream failed with %#x!\n", ret);
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
|
||
|
/* step 2.5 : save frame to file */
|
||
|
ret = sample_comm_save_frame_to_file(index, stream_proc_info, &stream, stream_buf_info, payload_type);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* step 2.6 : release stream */
|
||
|
ret = ss_mpi_venc_release_stream(index, &stream);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_release_stream failed!\n");
|
||
|
free(stream.pack);
|
||
|
stream.pack = TD_NULL;
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
|
||
|
/* step 2.7 : free pack nodes */
|
||
|
free(stream.pack);
|
||
|
stream.pack = TD_NULL;
|
||
|
stream_proc_info->picture_cnt[index]++;
|
||
|
if (payload_type[index] == OT_PT_JPEG) {
|
||
|
fclose(stream_proc_info->file[index]);
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
static td_void sample_comm_fd_isset(sample_comm_venc_stream_proc_info *stream_proc_info, fd_set *read_fds,
|
||
|
ot_venc_stream_buf_info *stream_buf_info, ot_payload_type *payload_type, struct_venc_getstream_para *para)
|
||
|
{
|
||
|
td_s32 i, ret;
|
||
|
|
||
|
for (i = 0; (i < stream_proc_info->chn_total) && (i < OT_VENC_MAX_CHN_NUM); i++) {
|
||
|
if (FD_ISSET(stream_proc_info->venc_fd[i], read_fds)) {
|
||
|
stream_proc_info->venc_chn = para->venc_chn[i];
|
||
|
ret = sample_comm_get_stream_from_one_channl(stream_proc_info, i, stream_buf_info, payload_type);
|
||
|
if (ret == SAMPLE_RETURN_CONTINUE) {
|
||
|
continue;
|
||
|
} else if (ret == SAMPLE_RETURN_BREAK) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* get stream from each channels and save them */
|
||
|
td_void *sample_comm_venc_get_venc_stream_proc(td_void *p)
|
||
|
{
|
||
|
td_s32 i, ret;
|
||
|
struct_venc_getstream_para *para = TD_NULL;
|
||
|
struct timeval timeout_val;
|
||
|
fd_set read_fds;
|
||
|
ot_payload_type payload_type[OT_VENC_MAX_CHN_NUM] = {0};
|
||
|
ot_venc_stream_buf_info stream_buf_info[OT_VENC_MAX_CHN_NUM];
|
||
|
sample_comm_venc_stream_proc_info stream_proc_info = {0};
|
||
|
|
||
|
prctl(PR_SET_NAME, "get_venc_stream", 0, 0, 0);
|
||
|
|
||
|
para = (struct_venc_getstream_para *)p;
|
||
|
stream_proc_info.chn_total = para->cnt;
|
||
|
stream_proc_info.save_heif = para->save_heif;
|
||
|
/* step 1: check & prepare save-file & venc-fd */
|
||
|
if (stream_proc_info.chn_total >= OT_VENC_MAX_CHN_NUM) {
|
||
|
sample_print("input count invalid\n");
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
ret = sample_comm_set_name_save_stream(&stream_proc_info, stream_buf_info, payload_type, para, OT_VENC_MAX_CHN_NUM);
|
||
|
if (ret == SAMPLE_RETURN_NULL) {
|
||
|
return TD_NULL;
|
||
|
} else if (ret == SAMPLE_RETURN_FAILURE) {
|
||
|
return (void *)TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* step 2: start to get streams of each channel. */
|
||
|
while (para->thread_start == TD_TRUE) {
|
||
|
FD_ZERO(&read_fds);
|
||
|
for (i = 0; (i < stream_proc_info.chn_total) && (i < OT_VENC_MAX_CHN_NUM); i++) {
|
||
|
FD_SET(stream_proc_info.venc_fd[i], &read_fds);
|
||
|
}
|
||
|
|
||
|
timeout_val.tv_sec = 2; /* 2 is a number */
|
||
|
timeout_val.tv_usec = 0;
|
||
|
ret = select(stream_proc_info.maxfd + 1, &read_fds, TD_NULL, TD_NULL, &timeout_val);
|
||
|
if (ret < 0) {
|
||
|
sample_print("select failed!\n");
|
||
|
break;
|
||
|
} else if (ret == 0) {
|
||
|
sample_print("get venc stream time out, exit thread\n");
|
||
|
continue;
|
||
|
} else {
|
||
|
sample_comm_fd_isset(&stream_proc_info, &read_fds, stream_buf_info, payload_type, para);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* step 3 : close save-file */
|
||
|
for (i = 0; i < stream_proc_info.chn_total; i++) {
|
||
|
if (payload_type[i] != OT_PT_JPEG) {
|
||
|
fclose(stream_proc_info.file[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
* function : bitrate_auto
|
||
|
******************************************************************************/
|
||
|
#define SAMPLE_VENC_WIDHT 640
|
||
|
#define SAMPLE_VENC_HEIGHT 480
|
||
|
#define SAMPLE_VENC_NUM 5
|
||
|
#define SAMPLE_VENC_FG_TYPE 5
|
||
|
#define QUERY_SLEEP 1000
|
||
|
|
||
|
td_void sample_comm_venc_set_region(td_u64 time, ot_venc_chn venc_chn, ot_venc_svc_rect_info *pst_svc_rect)
|
||
|
{
|
||
|
td_s32 j, ret;
|
||
|
td_u32 attrx[SAMPLE_VENC_NUM] = {32, 96, 128, 192, 256}; // 32 96 128 192 256 : X-coordinate
|
||
|
td_u32 attry[SAMPLE_VENC_NUM] = {32, 96, 128, 192, 256}; // 32 96 128 192 256 : Y-coordinate
|
||
|
td_u32 attrw[SAMPLE_VENC_NUM] = {32, 64, 96, 96, 64}; // 32 64 96 96 64 : width
|
||
|
td_u32 attrh[SAMPLE_VENC_NUM] = {32, 64, 96, 96, 64}; // 32 64 96 96 64 : height
|
||
|
td_u32 type[SAMPLE_VENC_NUM] = {0, 3, 4, 1, 2}; // 0 3 4 1 2 : type
|
||
|
pst_svc_rect->rect_num = SAMPLE_VENC_NUM;
|
||
|
pst_svc_rect->pts = time;
|
||
|
pst_svc_rect->base_resolution.width = SAMPLE_VENC_WIDHT;
|
||
|
pst_svc_rect->base_resolution.height = SAMPLE_VENC_HEIGHT;
|
||
|
|
||
|
for (j = 0; (j < SAMPLE_VENC_NUM) && (j < OT_VENC_MAX_SVC_RECT_NUM); j++) {
|
||
|
pst_svc_rect->detect_type[j] = type[j];
|
||
|
pst_svc_rect->rect_attr[j].x = attrx[j];
|
||
|
pst_svc_rect->rect_attr[j].y = attry[j];
|
||
|
pst_svc_rect->rect_attr[j].width = attrw[j];
|
||
|
pst_svc_rect->rect_attr[j].height = attrh[j];
|
||
|
}
|
||
|
ret = ss_mpi_venc_send_svc_region(venc_chn, pst_svc_rect);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("Set ss_mpi_venc_send_svc_region failed for %#x chn =%d\n", ret, venc_chn);
|
||
|
}
|
||
|
}
|
||
|
td_void sample_comm_venc_set_svc_param(ot_venc_chn venc_chn, ot_venc_svc_param *pst_svc_param)
|
||
|
{
|
||
|
td_s32 j, ret;
|
||
|
td_u32 qp_i[SAMPLE_VENC_NUM] = {2, 62, 94, 1, 0}; // 2 62 94 1 0 : fg I frame qp
|
||
|
td_u32 qp_p[SAMPLE_VENC_NUM] = {4, 58, 94, 2, 0}; // 4 58 94 2 0 : fg P frame qp
|
||
|
ret = ss_mpi_venc_get_svc_param(venc_chn, pst_svc_param);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("Set ss_mpi_venc_set_svc_param failed for %#x chn =%d\n", ret, venc_chn);
|
||
|
}
|
||
|
pst_svc_param->fg_protect_adaptive_en = TD_TRUE;
|
||
|
pst_svc_param->activity_region.qpmap_value_i = 0;
|
||
|
pst_svc_param->activity_region.qpmap_value_p = 0;
|
||
|
pst_svc_param->activity_region.skipmap_value = 0;
|
||
|
pst_svc_param->bg_region.qpmap_value_i = 2; // 2 :i frame bg qp
|
||
|
pst_svc_param->bg_region.qpmap_value_p = 6; // 6 :p frame bg qp
|
||
|
pst_svc_param->bg_region.skipmap_value = 0;
|
||
|
for (j = 0; (j < SAMPLE_VENC_NUM) && (j < SVC_RECT_TYPE_BUTT); j++) {
|
||
|
pst_svc_param->fg_region[j].qpmap_value_i = qp_i[j];
|
||
|
pst_svc_param->fg_region[j].qpmap_value_p = qp_p[j];
|
||
|
pst_svc_param->fg_region[j].skipmap_value = 0;
|
||
|
}
|
||
|
ret = ss_mpi_venc_set_svc_param(venc_chn, pst_svc_param);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("Set ss_mpi_venc_set_svc_param failed for %#x!\n", ret);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
td_void *sample_comm_venc_rateauto_stream_proc(td_void *p)
|
||
|
{
|
||
|
td_s32 i, ret;
|
||
|
struct_venc_rateauto_para *para;
|
||
|
ot_venc_svc_param svc_param;
|
||
|
ot_vpss_chn_attr vpss_chn_attr;
|
||
|
ot_venc_svc_rect_info svc_rect_info = {0};
|
||
|
para = (struct_venc_rateauto_para *)p;
|
||
|
ot_video_frame_info video_frame;
|
||
|
prctl(PR_SET_NAME, "get_venc_rateauto_stream", 0, 0, 0);
|
||
|
if (para->cnt >= OT_VENC_MAX_CHN_NUM) {
|
||
|
sample_print("input count invalid\n");
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
for (i = 0; (i < para->cnt) && (i < OT_VENC_MAX_CHN_NUM); i++) {
|
||
|
ret = ss_mpi_vpss_get_chn_attr(para->vpss_grp, para->vpss_chn[i], &vpss_chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_get_chn_attr err: 0x%x", ret);
|
||
|
}
|
||
|
|
||
|
vpss_chn_attr.depth = 3; /* 3 is a number */
|
||
|
ret = ss_mpi_vpss_set_chn_attr(para->vpss_grp, para->vpss_chn[i], &vpss_chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_set_chn_attr err: 0x%x", ret);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
while (para->thread_start == TD_TRUE) {
|
||
|
for (i = 0; (i < para->cnt) && (i < OT_VENC_MAX_CHN_NUM); i++) {
|
||
|
ret = ss_mpi_vpss_get_chn_frame(para->vpss_grp, para->vpss_chn[i], &video_frame, QUERY_SLEEP);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_get_chn_frame err:0x%x venc_chn = %d\n", ret, para->venc_chn[i]);
|
||
|
continue;
|
||
|
}
|
||
|
ret = ss_mpi_vpss_release_chn_frame(para->vpss_grp, para->vpss_chn[i], &video_frame);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_vpss_release_chn_frame err:0x%x\n", ret);
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
ret = ss_mpi_venc_enable_svc(para->venc_chn[i], TD_TRUE);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("Set ss_mpi_venc_enable_svc failed for %#x!\n", ret);
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
sample_comm_venc_set_region(video_frame.video_frame.pts, para->venc_chn[i], &svc_rect_info);
|
||
|
sample_comm_venc_set_svc_param(para->venc_chn[i], &svc_param);
|
||
|
}
|
||
|
usleep(QUERY_SLEEP);
|
||
|
}
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_set_file_name_svc_t(sample_comm_venc_stream_proc_info *stream_proc_info, td_s32 index)
|
||
|
{
|
||
|
if (snprintf_s(stream_proc_info->file_name[index], FILE_NAME_LEN, FILE_NAME_LEN - 1, "./") < 0) {
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
if (realpath(stream_proc_info->file_name[index], stream_proc_info->real_file_name[index]) == TD_NULL) {
|
||
|
printf("file path error\n");
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
if (snprintf_s(stream_proc_info->real_file_name[index], FILE_NAME_LEN, FILE_NAME_LEN - 1,
|
||
|
"tid%d%s", index, stream_proc_info->file_postfix) < 0) {
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_set_name_save_stream_svc_t(sample_comm_venc_stream_proc_info *stream_proc_info,
|
||
|
ot_venc_stream_buf_info *stream_buf_info, td_s32 venc_max_chn)
|
||
|
{
|
||
|
td_s32 i, ret, cnt, fd;
|
||
|
ot_venc_chn_attr venc_chn_attr;
|
||
|
ot_payload_type payload_type[OT_VENC_MAX_CHN_NUM];
|
||
|
ot_unused(venc_max_chn);
|
||
|
|
||
|
for (i = 0; i < stream_proc_info->chn_total; i++) {
|
||
|
/* decide the stream file name, and open file to save stream */
|
||
|
stream_proc_info->venc_chn = i;
|
||
|
ret = ss_mpi_venc_get_chn_attr(stream_proc_info->venc_chn, &venc_chn_attr);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_get_chn_attr chn[%d] failed with %#x!\n", stream_proc_info->venc_chn, ret);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
payload_type[i] = venc_chn_attr.venc_attr.type;
|
||
|
|
||
|
ret = sample_comm_venc_get_file_postfix(payload_type[i], stream_proc_info->file_postfix,
|
||
|
sizeof(stream_proc_info->file_postfix));
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("sample_comm_venc_get_file_postfix [%d] failed with %#x!\n",
|
||
|
venc_chn_attr.venc_attr.type, ret);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
|
||
|
for (cnt = 0; cnt < 3; cnt++) { /* 3 is a number */
|
||
|
if (sample_comm_set_file_name_svc_t(stream_proc_info, (i + cnt)) != TD_SUCCESS) {
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
|
||
|
stream_proc_info->file[i + cnt] = fopen(stream_proc_info->real_file_name[i + cnt], "wb");
|
||
|
if (!stream_proc_info->file[i + cnt]) {
|
||
|
sample_print("open file[%s] failed!\n", stream_proc_info->real_file_name[i + cnt]);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
fd = fileno(stream_proc_info->file[i + cnt]);
|
||
|
fchmod(fd, S_IRUSR | S_IWUSR);
|
||
|
}
|
||
|
|
||
|
/* set venc fd. */
|
||
|
stream_proc_info->venc_fd[i] = ss_mpi_venc_get_fd(i);
|
||
|
if (stream_proc_info->venc_fd[i] < 0) {
|
||
|
sample_print("ss_mpi_venc_get_fd failed with %#x!\n", stream_proc_info->venc_fd[i]);
|
||
|
return SAMPLE_RETURN_NULL;
|
||
|
}
|
||
|
if (stream_proc_info->maxfd <= stream_proc_info->venc_fd[i]) {
|
||
|
stream_proc_info->maxfd = stream_proc_info->venc_fd[i];
|
||
|
}
|
||
|
ret = ss_mpi_venc_get_stream_buf_info(i, &stream_buf_info[i]);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_get_stream_buf_info failed with %#x!\n", ret);
|
||
|
return SAMPLE_RETURN_FAILURE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_save_frame_to_file_svc_t(td_s32 index, sample_comm_venc_stream_proc_info *stream_proc_info,
|
||
|
ot_venc_stream *stream, ot_venc_stream_buf_info *stream_buf_info)
|
||
|
{
|
||
|
td_s32 cnt, ret;
|
||
|
|
||
|
for (cnt = 0; cnt < 3; cnt++) { /* 3 is a number */
|
||
|
switch (cnt) {
|
||
|
case 0: /* 0 is a number */
|
||
|
if (stream->h264_info.ref_type == OT_VENC_BASE_IDR_SLICE ||
|
||
|
stream->h264_info.ref_type == OT_VENC_BASE_P_SLICE_REF_BY_BASE) {
|
||
|
#ifndef __LITEOS__
|
||
|
ot_unused(stream_buf_info);
|
||
|
ret = sample_comm_venc_save_stream(stream_proc_info->file[index + cnt], stream);
|
||
|
#else
|
||
|
ret = sample_comm_venc_save_stream_phys_addr(stream_proc_info->file[index + cnt],
|
||
|
&stream_buf_info[index], stream);
|
||
|
#endif
|
||
|
}
|
||
|
break;
|
||
|
case 1: /* 1 is a number */
|
||
|
if (stream->h264_info.ref_type == OT_VENC_BASE_IDR_SLICE ||
|
||
|
stream->h264_info.ref_type == OT_VENC_BASE_P_SLICE_REF_BY_BASE ||
|
||
|
stream->h264_info.ref_type == OT_VENC_BASE_P_SLICE_REF_BY_ENHANCE) {
|
||
|
#ifndef __LITEOS__
|
||
|
ret = sample_comm_venc_save_stream(stream_proc_info->file[index + cnt], stream);
|
||
|
#else
|
||
|
ret = sample_comm_venc_save_stream_phys_addr(stream_proc_info->file[index + cnt],
|
||
|
&stream_buf_info[index], stream);
|
||
|
#endif
|
||
|
}
|
||
|
break;
|
||
|
case 2: /* 2 is a number */
|
||
|
#ifndef __LITEOS__
|
||
|
ret = sample_comm_venc_save_stream(stream_proc_info->file[index + cnt], stream);
|
||
|
#else
|
||
|
ret = sample_comm_venc_save_stream_phys_addr(stream_proc_info->file[index + cnt],
|
||
|
&stream_buf_info[index], stream);
|
||
|
#endif
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
free(stream->pack);
|
||
|
stream->pack = TD_NULL;
|
||
|
sample_print("save stream failed!\n");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static td_s32 sample_comm_get_stream_from_one_channl_svc_t(sample_comm_venc_stream_proc_info *stream_proc_info,
|
||
|
td_s32 index, ot_venc_stream_buf_info *stream_buf_info)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ot_venc_stream stream;
|
||
|
ot_venc_chn_status stat;
|
||
|
|
||
|
/* step 2.1 : query how many packs in one-frame stream. */
|
||
|
if (memset_s(&stream, sizeof(stream), 0, sizeof(stream)) != EOK) {
|
||
|
printf("call memset_s error\n");
|
||
|
}
|
||
|
ret = ss_mpi_venc_query_status(index, &stat);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("ss_mpi_venc_query chn[%d] failed with %#x!\n", index, ret);
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
|
||
|
if (stat.cur_packs == 0) {
|
||
|
sample_print("NOTE: current frame is TD_NULL!\n");
|
||
|
return SAMPLE_RETURN_CONTINUE;
|
||
|
}
|
||
|
/* step 2.3 : malloc corresponding number of pack nodes. */
|
||
|
stream.pack = (ot_venc_pack *)malloc(sizeof(ot_venc_pack) * stat.cur_packs);
|
||
|
if (stream.pack == TD_NULL) {
|
||
|
sample_print("malloc stream pack failed!\n");
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
/* step 2.4 : call mpi to get one-frame stream */
|
||
|
stream.pack_cnt = stat.cur_packs;
|
||
|
ret = ss_mpi_venc_get_stream(index, &stream, TD_TRUE);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
free(stream.pack);
|
||
|
stream.pack = TD_NULL;
|
||
|
sample_print("ss_mpi_venc_get_stream failed with %#x!\n", ret);
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
/* step 2.5 : save frame to file */
|
||
|
sample_comm_save_frame_to_file_svc_t(index, stream_proc_info, &stream, stream_buf_info);
|
||
|
|
||
|
/* step 2.6 : release stream */
|
||
|
ret = ss_mpi_venc_release_stream(index, &stream);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
free(stream.pack);
|
||
|
stream.pack = TD_NULL;
|
||
|
return SAMPLE_RETURN_BREAK;
|
||
|
}
|
||
|
/* step 2.7 : free pack nodes */
|
||
|
free(stream.pack);
|
||
|
stream.pack = TD_NULL;
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_void sample_comm_fd_isset_svc_t(sample_comm_venc_stream_proc_info *stream_proc_info,
|
||
|
fd_set *read_fds, ot_venc_stream_buf_info *stream_buf_info, td_s32 venc_max_chn)
|
||
|
{
|
||
|
td_s32 i, ret;
|
||
|
ot_unused(venc_max_chn);
|
||
|
|
||
|
for (i = 0; i < stream_proc_info->chn_total; i++) {
|
||
|
if (FD_ISSET(stream_proc_info->venc_fd[i], read_fds)) {
|
||
|
ret = sample_comm_get_stream_from_one_channl_svc_t(stream_proc_info, i, stream_buf_info);
|
||
|
if (ret == SAMPLE_RETURN_CONTINUE) {
|
||
|
continue;
|
||
|
} else if (ret == SAMPLE_RETURN_BREAK) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* get svc_t stream from h264 channels and save them */
|
||
|
td_void *sample_comm_venc_get_venc_stream_proc_svc_t(td_void *p)
|
||
|
{
|
||
|
td_s32 i, ret;
|
||
|
td_s32 cnt = 0;
|
||
|
|
||
|
struct_venc_getstream_para *para = TD_NULL;
|
||
|
struct timeval timeout_val;
|
||
|
fd_set read_fds;
|
||
|
ot_venc_stream_buf_info stream_buf_info[OT_VENC_MAX_CHN_NUM];
|
||
|
sample_comm_venc_stream_proc_info stream_proc_info = {0};
|
||
|
|
||
|
para = (struct_venc_getstream_para *)p;
|
||
|
stream_proc_info.chn_total = para->cnt;
|
||
|
stream_proc_info.save_heif = para->save_heif;
|
||
|
|
||
|
/* step 1: check & prepare save-file & venc-fd */
|
||
|
if (stream_proc_info.chn_total >= OT_VENC_MAX_CHN_NUM) {
|
||
|
sample_print("input count invalid\n");
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
ret = sample_comm_set_name_save_stream_svc_t(&stream_proc_info, stream_buf_info, OT_VENC_MAX_CHN_NUM);
|
||
|
if (ret == SAMPLE_RETURN_NULL) {
|
||
|
return TD_NULL;
|
||
|
} else if (ret == SAMPLE_RETURN_FAILURE) {
|
||
|
return (void *)TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* step 2: start to get streams of each channel. */
|
||
|
while (para->thread_start == TD_TRUE) {
|
||
|
FD_ZERO(&read_fds);
|
||
|
for (i = 0; i < stream_proc_info.chn_total; i++) {
|
||
|
FD_SET(stream_proc_info.venc_fd[i], &read_fds);
|
||
|
}
|
||
|
timeout_val.tv_sec = 2; /* 2 is a number */
|
||
|
timeout_val.tv_usec = 0;
|
||
|
ret = select(stream_proc_info.maxfd + 1, &read_fds, TD_NULL, TD_NULL, &timeout_val);
|
||
|
if (ret < 0) {
|
||
|
sample_print("select failed!\n");
|
||
|
break;
|
||
|
} else if (ret == 0) {
|
||
|
sample_print("get venc stream time out, exit thread\n");
|
||
|
continue;
|
||
|
} else {
|
||
|
sample_comm_fd_isset_svc_t(&stream_proc_info, &read_fds, stream_buf_info, OT_VENC_MAX_CHN_NUM);
|
||
|
}
|
||
|
}
|
||
|
/* step 3 : close save-file */
|
||
|
for (i = 0; i < stream_proc_info.chn_total; i++) {
|
||
|
for (cnt = 0; cnt < 3; cnt++) { /* 3 is a number */
|
||
|
if (stream_proc_info.file[i + cnt]) {
|
||
|
fclose(stream_proc_info.file[i + cnt]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
td_void sample_comm_venc_set_save_heif(td_bool save_heif)
|
||
|
{
|
||
|
g_para.save_heif = save_heif;
|
||
|
sample_print("set save heif flag: %d!\n", save_heif);
|
||
|
}
|
||
|
|
||
|
/* start get venc stream process thread */
|
||
|
td_s32 sample_comm_venc_start_get_stream(ot_venc_chn *venc_chn, td_s32 cnt)
|
||
|
{
|
||
|
td_s32 i;
|
||
|
|
||
|
g_para.thread_start = TD_TRUE;
|
||
|
g_para.cnt = cnt;
|
||
|
for (i = 0; (i < cnt) && (i < OT_VENC_MAX_CHN_NUM); i++) {
|
||
|
g_para.venc_chn[i] = venc_chn[i];
|
||
|
}
|
||
|
|
||
|
return pthread_create(&g_venc_pid, 0, sample_comm_venc_get_venc_stream_proc, (td_void *)&g_para);
|
||
|
}
|
||
|
/******************************************************************************
|
||
|
* function : start rate auto process thread
|
||
|
******************************************************************************/
|
||
|
td_s32 sample_comm_venc_rateauto_start(ot_venc_chn venc_chn[], td_s32 cnt, ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn[])
|
||
|
{
|
||
|
td_s32 i;
|
||
|
|
||
|
g_venc_rateauto_frame_param.thread_start = TD_TRUE;
|
||
|
g_venc_rateauto_frame_param.cnt = cnt;
|
||
|
g_venc_rateauto_frame_param.vpss_grp = vpss_grp;
|
||
|
for (i = 0; (i < cnt) && (i < OT_VENC_MAX_CHN_NUM); i++) {
|
||
|
g_venc_rateauto_frame_param.venc_chn[i] = venc_chn[i];
|
||
|
g_venc_rateauto_frame_param.vpss_chn[i] = vpss_chn[i];
|
||
|
}
|
||
|
|
||
|
return pthread_create(&g_venc_rateauto_pid, 0, sample_comm_venc_rateauto_stream_proc,
|
||
|
(td_void *)&g_venc_rateauto_frame_param);
|
||
|
}
|
||
|
/* start get venc svc-t stream process thread */
|
||
|
td_s32 sample_comm_venc_start_get_stream_svc_t(td_s32 cnt)
|
||
|
{
|
||
|
g_para.thread_start = TD_TRUE;
|
||
|
g_para.cnt = cnt;
|
||
|
return pthread_create(&g_venc_pid, 0, sample_comm_venc_get_venc_stream_proc_svc_t, (td_void *)&g_para);
|
||
|
}
|
||
|
|
||
|
/* stop get venc stream process. */
|
||
|
td_s32 sample_comm_venc_stop_get_stream(td_s32 chn_num)
|
||
|
{
|
||
|
td_s32 i;
|
||
|
for (i = 0; i < chn_num; i++) {
|
||
|
if (ss_mpi_venc_stop_chn(i) != TD_SUCCESS) {
|
||
|
sample_print("chn %d ss_mpi_venc_stop_recv_pic failed!\n", i);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (g_para.thread_start == TD_TRUE) {
|
||
|
g_para.thread_start = TD_FALSE;
|
||
|
pthread_join(g_venc_pid, 0);
|
||
|
}
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_stop_send_qpmap_frame(td_void)
|
||
|
{
|
||
|
if (g_qpmap_send_frame_para.thread_start == TD_TRUE) {
|
||
|
g_qpmap_send_frame_para.thread_start = TD_FALSE;
|
||
|
pthread_join(g_venc_qpmap_pid, 0);
|
||
|
}
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_stop_send_roimap_frame(td_void)
|
||
|
{
|
||
|
if (g_roimap_frame_param.thread_start == TD_TRUE) {
|
||
|
g_roimap_frame_param.thread_start = TD_FALSE;
|
||
|
pthread_join(g_venc_roimap_pid, 0);
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
td_s32 sample_comm_venc_stop_rateauto(ot_venc_chn chn[], td_s32 cnt)
|
||
|
{
|
||
|
td_s32 i, ret;
|
||
|
|
||
|
prctl(PR_SET_NAME, "sample_comm_venc_stop_rateauto", 0, 0, 0);
|
||
|
|
||
|
ot_venc_svc_param svc_param = {0};
|
||
|
|
||
|
ot_venc_chn venc_chn;
|
||
|
ot_venc_svc_rect_info svc_rect_info = {0};
|
||
|
if (g_venc_rateauto_frame_param.thread_start == TD_TRUE) {
|
||
|
g_venc_rateauto_frame_param.thread_start = TD_FALSE;
|
||
|
pthread_join(g_venc_rateauto_pid, 0);
|
||
|
for (i = 0; i < cnt; i++) {
|
||
|
venc_chn = chn[i];
|
||
|
ret = ss_mpi_venc_enable_svc(venc_chn, TD_TRUE);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("Set ss_mpi_venc_enable_svc failed for %#x chn =%d\n", ret, venc_chn);
|
||
|
}
|
||
|
if (memset_s(&svc_rect_info, sizeof(ot_venc_svc_rect_info), 0, sizeof(ot_venc_svc_rect_info)) != EOK) {
|
||
|
printf("call memset_s error\n");
|
||
|
}
|
||
|
ret = ss_mpi_venc_send_svc_region(venc_chn, &svc_rect_info);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("Set ss_mpi_venc_send_svc_region failed for %#x chn =%d\n", ret, venc_chn);
|
||
|
}
|
||
|
ret = ss_mpi_venc_get_svc_param(venc_chn, &svc_param);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("Set ss_mpi_venc_set_svc_param failed for %#x chn =%d\n", ret, venc_chn);
|
||
|
}
|
||
|
if (memset_s(&svc_param, sizeof(ot_venc_svc_param), 0, sizeof(ot_venc_svc_param)) != EOK) {
|
||
|
printf("call memset_s error\n");
|
||
|
}
|
||
|
ret = ss_mpi_venc_set_svc_param(venc_chn, &svc_param);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("Set ss_mpi_venc_set_svc_param failed for %#x chn =%d\n", ret, venc_chn);
|
||
|
}
|
||
|
ret = ss_mpi_venc_enable_svc(venc_chn, TD_FALSE);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
sample_print("Set ss_mpi_venc_enable_svc failed for %#x chn =%d\n", ret, venc_chn);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
td_s32 sample_comm_venc_plan_to_semi(td_u8 *u, td_s32 u_stride, td_u8 *v, td_s32 pic_height)
|
||
|
{
|
||
|
td_s32 i;
|
||
|
td_u8 *tmp_u = TD_NULL;
|
||
|
td_u8 *ptu = TD_NULL;
|
||
|
td_u8 *tmp_v = TD_NULL;
|
||
|
td_u8 *ptv = TD_NULL;
|
||
|
td_s32 haf_w = u_stride / 2; /* 2: half */
|
||
|
td_s32 haf_h = pic_height / 2; /* 2: half */
|
||
|
td_s32 size = haf_w * haf_h;
|
||
|
|
||
|
tmp_u = malloc(size);
|
||
|
if (tmp_u == TD_NULL) {
|
||
|
printf("malloc buf failed\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
ptu = tmp_u;
|
||
|
|
||
|
tmp_v = malloc(size);
|
||
|
if (tmp_v == TD_NULL) {
|
||
|
printf("malloc buf failed\n");
|
||
|
free(tmp_u);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
ptv = tmp_v;
|
||
|
|
||
|
if (memcpy_s(tmp_u, size, u, size) != EOK) {
|
||
|
printf("call memcpy_s error\n");
|
||
|
free(tmp_u);
|
||
|
free(tmp_v);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
if (memcpy_s(tmp_v, size, v, size) != EOK) {
|
||
|
printf("call memcpy_s error\n");
|
||
|
free(tmp_u);
|
||
|
free(tmp_v);
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
for (i = 0; i < (size / 2); i++) { /* 2: half */
|
||
|
*u++ = *tmp_v++;
|
||
|
*u++ = *tmp_u++;
|
||
|
}
|
||
|
for (i = 0; i < (size / 2); i++) { /* 2: half */
|
||
|
*v++ = *tmp_v++;
|
||
|
*v++ = *tmp_u++;
|
||
|
}
|
||
|
free(ptu);
|
||
|
free(ptv);
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|