2135 lines
86 KiB
C
Executable File
2135 lines
86 KiB
C
Executable File
/*
|
||
* Copyright (c) XMEDIA. All rights reserved.
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <signal.h>
|
||
#include <string.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/types.h>
|
||
#include <unistd.h>
|
||
#include <pthread.h>
|
||
#include <errno.h>
|
||
#include <stdint.h>
|
||
#include <sys/prctl.h>
|
||
|
||
#include "math_fun.h"
|
||
#include "xmedia_type.h"
|
||
#include "xmedia_debug.h"
|
||
#include "xmedia_vgs.h"
|
||
#include "sample_comm.h"
|
||
#include "sample_comm_sys.h"
|
||
#include "sample_comm_venc.h"
|
||
#include "xcam_livestream_rtsp_server.h"
|
||
#include "xcam_liveserver.h"
|
||
|
||
static sample_venc_getstream_para g_get_stream_param;
|
||
static pthread_t g_venc_pid;
|
||
static pthread_t g_venc_qpmap_pid;
|
||
static sample_venc_qpmap_sendfrm_para g_qpmap_sendfrm_para;
|
||
xmedia_bool g_user_start = XMEDIA_FALSE;
|
||
|
||
xmedia_s32 sample_comm_venc_get_file_post_fix(xmedia_payload_type payload, xmedia_char *file_post_fix)
|
||
{
|
||
xmedia_char *post_fix = XMEDIA_NULL;
|
||
|
||
switch(payload) {
|
||
case PT_H264:
|
||
post_fix = ".h264";
|
||
break;
|
||
case PT_H265:
|
||
post_fix = ".h265";
|
||
break;
|
||
case PT_JPEG:
|
||
post_fix = ".jpg";
|
||
break;
|
||
case PT_MJPEG:
|
||
post_fix = ".mjp";
|
||
break;
|
||
case PT_PRORES:
|
||
post_fix = ".prores";
|
||
break;
|
||
default:
|
||
printf("Payload type err!\n");
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
|
||
memcpy(file_post_fix, post_fix, strlen(post_fix) + 1);
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_save_stream(FILE* pFd, xmedia_venc_stream* pstStream)
|
||
{
|
||
xmedia_s32 i;
|
||
|
||
for (i = 0; i < pstStream->pack_count; i++) {
|
||
fwrite(pstStream->pack[i].vir_addr + pstStream->pack[i].offset,
|
||
pstStream->pack[i].len - pstStream->pack[i].offset, 1, pFd);
|
||
}
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_save_jpeg_stream(xmedia_s32 chn,FILE* fd, xmedia_venc_stream* pst_stream , xmedia_u32 recv_cnt, char *save_path)
|
||
{
|
||
xmedia_s32 i = 0;
|
||
xmedia_u32 pack_cnt;
|
||
|
||
if (pst_stream->pack_count == 1) {
|
||
pack_cnt = 1;
|
||
} else {
|
||
pack_cnt = 2;
|
||
}
|
||
for (i = 0; i < pack_cnt; i++) {
|
||
fwrite(pst_stream->pack[i].vir_addr + pst_stream->pack[i].offset,
|
||
pst_stream->pack[i].len - pst_stream->pack[i].offset, 1, fd);
|
||
fflush(fd);
|
||
}
|
||
|
||
if (pst_stream->pack_count > 2) {
|
||
/* save mpf */
|
||
for (i = 2; i < pst_stream->pack_count; i += 2) {
|
||
char mpf_file[128] = {0};
|
||
xmedia_u32 mpf_cnt = i / 2 - 1;
|
||
snprintf(mpf_file, 128, "%s/chn%d_snap_%d_mpf%d.jpg", save_path, chn, recv_cnt, mpf_cnt);
|
||
FILE* file_mpf = NULL;
|
||
file_mpf = fopen(mpf_file, "wb");
|
||
if (file_mpf == NULL) {
|
||
SAMPLE_PRT("open file %s err\n", mpf_file);
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
chmod(mpf_file, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||
fwrite(pst_stream->pack[i].vir_addr + pst_stream->pack[i].offset,
|
||
pst_stream->pack[i].len - pst_stream->pack[i].offset, 1, file_mpf);
|
||
fflush(file_mpf);
|
||
fwrite(pst_stream->pack[i+1].vir_addr + pst_stream->pack[i+1].offset,
|
||
pst_stream->pack[i+1].len - pst_stream->pack[i+1].offset, 1, file_mpf);
|
||
fflush(file_mpf);
|
||
fclose(file_mpf);
|
||
SAMPLE_PRT("save large thumb_nail:%s ok\n", mpf_file);
|
||
}
|
||
}
|
||
|
||
i--;
|
||
if ((pst_stream->pack[i].data_type.jpege_type == JPEGE_PACK_HEAD) ||
|
||
(pst_stream->pack[i].data_type.jpege_type == JPEGE_PACK_ECS)) {
|
||
/* When jpeg dividing slice or venc_attr.by_frame = XMEDIA_FALSE,
|
||
* do not close cur file until the last pack of a frame is received
|
||
*/
|
||
return XMEDIA_FAILURE;
|
||
} else if (pst_stream->pack[i].data_type.jpege_type < JPEGE_PACK_MAX) {
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_save_jpeg_thum(xmedia_char *result_path, xmedia_venc_stream* stream_pack, xmedia_u32 chn, xmedia_u32 recv_cnt)
|
||
{
|
||
if (stream_pack->pack[0].data_num == 1) {
|
||
char dcf_file[128] = {0};
|
||
snprintf(dcf_file, 128, "%s/chn%d_snap_thumb_%d.jpg", result_path, chn, recv_cnt);
|
||
FILE* file_dcf = NULL;
|
||
file_dcf = fopen(dcf_file, "wb");
|
||
if (file_dcf == NULL) {
|
||
SAMPLE_PRT("open dcf file %s err\n", dcf_file);
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
chmod(dcf_file, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||
fwrite(stream_pack->pack[0].vir_addr + stream_pack->pack[0].pack_info[0].pack_offset,
|
||
stream_pack->pack[0].pack_info[0].pack_length, 1, file_dcf);
|
||
fflush(file_dcf);
|
||
SAMPLE_PRT("save thumb_nail:%s ok\n", dcf_file);
|
||
} else {
|
||
SAMPLE_PRT("stream pack not find dcf!\n");
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_start_chn(xmedia_s32 venc_chn)
|
||
{
|
||
xmedia_s32 ret;
|
||
xmedia_venc_recv_pic_param recv_param;
|
||
|
||
recv_param.recv_pic_num = -1;
|
||
|
||
ret = xmedia_venc_start_recv_frame(venc_chn, &recv_param);
|
||
CHECK_RET(ret,"start recv frame");
|
||
|
||
return ret;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_stop_chn(xmedia_s32 venc_chn)
|
||
{
|
||
xmedia_s32 ret;
|
||
|
||
ret = xmedia_venc_stop_recv_frame(venc_chn);
|
||
CHECK_RET(ret,"stop recv frame");
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_get_default_gop_attr(xmedia_venc_gop_mode gop_mode, xmedia_venc_gop_attr *gop_attr)
|
||
{
|
||
switch(gop_mode) {
|
||
case VENC_GOPMODE_NORMALP:
|
||
gop_attr->gop_mode = VENC_GOPMODE_NORMALP;
|
||
gop_attr->normal_p.ip_qp_delta = 0;
|
||
break;
|
||
case VENC_GOPMODE_SMARTP:
|
||
case VENC_GOPMODE_ADVSMARTP:
|
||
gop_attr->gop_mode = VENC_GOPMODE_SMARTP;
|
||
gop_attr->smart_p.bg_qp_delta = 0;
|
||
gop_attr->smart_p.vi_qp_delta = 0;
|
||
gop_attr->smart_p.bg_interval = 90;
|
||
break;
|
||
default:
|
||
SAMPLE_PRT("not support the gop mode !\n");
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_void sample_comm_venc_get_default_chn_info(xmedia_video_size res,xmedia_u32 framerate,sample_venc_chn_info *chn_info)
|
||
{
|
||
chn_info->width = res.width;
|
||
chn_info->height = res.height;
|
||
chn_info->profile = (chn_info->payload_type == PT_H264) ? 2 : 0;
|
||
chn_info->use_default_gop_attr = XMEDIA_TRUE;
|
||
chn_info->rcn_ref_share_buf = XMEDIA_TRUE;
|
||
chn_info->src_frame_rate = framerate;
|
||
chn_info->dst_frame_rate = framerate;
|
||
|
||
if (PT_JPEG == chn_info->payload_type) {
|
||
chn_info->jpeg_attr.support_dcf = chn_info->support_dcf;
|
||
chn_info->jpeg_attr.mpf_cfg.large_thumbnail_num = chn_info->mpf_cnt;
|
||
chn_info->jpeg_attr.mpf_cfg.large_thumbnail_size[0].width = 1280;
|
||
chn_info->jpeg_attr.mpf_cfg.large_thumbnail_size[0].height = 720;
|
||
chn_info->jpeg_attr.mpf_cfg.large_thumbnail_size[1].width = 640;
|
||
chn_info->jpeg_attr.mpf_cfg.large_thumbnail_size[1].height = 480;
|
||
chn_info->jpeg_attr.rcv_mode = VENC_PIC_RECEIVE_SINGLE;
|
||
}
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_set_rc_param(xmedia_s32 venc_chn)
|
||
{
|
||
xmedia_s32 ret;
|
||
xmedia_venc_rc_param rc_param;
|
||
xmedia_venc_chn_attr chn_attr;
|
||
|
||
ret = xmedia_venc_get_chn_attr(venc_chn,&chn_attr);
|
||
CHECK_RET(ret,"get venc chn attr");
|
||
|
||
if (chn_attr.venc_attr.en_type != PT_JPEG) {
|
||
ret = xmedia_venc_get_rc_param(venc_chn,&rc_param);
|
||
CHECK_RET(ret,"get venc rc param");
|
||
}
|
||
|
||
if (VENC_RC_MODE_H264CBR == chn_attr.rc_attr.rc_mode) {
|
||
rc_param.param_h264_cbr.max_re_enc_times = 0;
|
||
} else if (VENC_RC_MODE_H264VBR == chn_attr.rc_attr.rc_mode) {
|
||
rc_param.param_h264_vbr.max_re_enc_times = 0;
|
||
} else if (VENC_RC_MODE_H265CBR == chn_attr.rc_attr.rc_mode) {
|
||
rc_param.param_h265_cbr.max_re_enc_times = 0;
|
||
} else if (VENC_RC_MODE_H265VBR == chn_attr.rc_attr.rc_mode) {
|
||
rc_param.param_h265_vbr.max_re_enc_times = 0;
|
||
} else {
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
ret = xmedia_venc_set_rc_param(venc_chn,&rc_param);
|
||
CHECK_RET(ret,"set venc rc param");
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_create_chn(sample_venc_chn_info *chn_param)
|
||
{
|
||
xmedia_s32 ret = 0;
|
||
xmedia_venc_chn_attr venc_attr;
|
||
xmedia_u32 framerate;
|
||
xmedia_u32 stat_time;
|
||
xmedia_u32 gop = chn_param->dst_frame_rate;
|
||
pic_size_e pic_size;
|
||
xmedia_u32 ext_size = 0;
|
||
|
||
memset(&venc_attr, 0, sizeof(xmedia_venc_chn_attr));
|
||
|
||
venc_attr.venc_attr.en_type = chn_param->payload_type;
|
||
venc_attr.venc_attr.max_pic_width = chn_param->width;
|
||
venc_attr.venc_attr.max_pic_height = chn_param->height;
|
||
venc_attr.venc_attr.pic_width = chn_param->width;
|
||
venc_attr.venc_attr.pic_height = chn_param->height;
|
||
venc_attr.venc_attr.profile = chn_param->profile;
|
||
venc_attr.venc_attr.by_frame = XMEDIA_TRUE;
|
||
|
||
if (venc_attr.venc_attr.en_type == PT_JPEG) {
|
||
if (chn_param->jpeg_attr.mpf_cfg.large_thumbnail_num > 0) {
|
||
ext_size = ALIGN_UP(chn_param->jpeg_attr.mpf_cfg.large_thumbnail_size[0].width, 16) * \
|
||
ALIGN_UP(chn_param->jpeg_attr.mpf_cfg.large_thumbnail_size[0].height, 16);
|
||
}
|
||
if (chn_param->jpeg_attr.mpf_cfg.large_thumbnail_num == 2) {
|
||
ext_size += ALIGN_UP(chn_param->jpeg_attr.mpf_cfg.large_thumbnail_size[1].width, 16) * \
|
||
ALIGN_UP(chn_param->jpeg_attr.mpf_cfg.large_thumbnail_size[1].height, 16);
|
||
}
|
||
}
|
||
|
||
if (chn_param->str_buffer_size != 0) {
|
||
venc_attr.venc_attr.stream_buf_size = chn_param->str_buffer_size;
|
||
} else {
|
||
if (venc_attr.venc_attr.en_type == PT_MJPEG || venc_attr.venc_attr.en_type == PT_JPEG) {
|
||
venc_attr.venc_attr.stream_buf_size = ALIGN_UP(venc_attr.venc_attr.pic_width, 16) * ALIGN_UP(venc_attr.venc_attr.pic_height, 16) * 2 + ext_size;
|
||
} else {
|
||
venc_attr.venc_attr.stream_buf_size = ALIGN_UP(venc_attr.venc_attr.pic_width * venc_attr.venc_attr.pic_height * 3 / 8, 64);
|
||
}
|
||
}
|
||
|
||
if (chn_param->use_default_gop_attr == XMEDIA_TRUE) {
|
||
ret = sample_comm_venc_get_default_gop_attr(chn_param->venc_gop_attr.gop_mode, &chn_param->venc_gop_attr);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
|
||
SAMPLE_PRT("get gop attr failed !\n");
|
||
return ret;
|
||
}
|
||
}
|
||
|
||
if (VENC_GOPMODE_SMARTP == chn_param->venc_gop_attr.gop_mode) {
|
||
stat_time = chn_param->venc_gop_attr.smart_p.bg_interval/gop;
|
||
} else {
|
||
stat_time = 2;
|
||
}
|
||
|
||
pic_size = sample_comm_sys_get_picszie_by_wxh(chn_param->width, chn_param->height);
|
||
framerate = chn_param->dst_frame_rate;
|
||
|
||
switch (venc_attr.venc_attr.en_type) {
|
||
case PT_H265: {
|
||
if (VENC_RC_MODE_H265CBR == chn_param->rc_mode) {
|
||
xmedia_venc_h265_cbr h265_cbr;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_H265CBR;
|
||
h265_cbr.gop = gop;
|
||
h265_cbr.stat_time = stat_time; /* stream rate statics time(s) */
|
||
h265_cbr.src_frame_rate = chn_param->src_frame_rate;
|
||
h265_cbr.dst_frame_rate = chn_param->dst_frame_rate; /* target frame rate */
|
||
switch (pic_size) {
|
||
case PIC_VGA:
|
||
case PIC_720P:
|
||
h265_cbr.bit_rate = (1024 * 1 * framerate)/30;
|
||
break;
|
||
case PIC_1080P:
|
||
case PIC_2304x1296: //300W
|
||
h265_cbr.bit_rate = (1024 * 2 * framerate)/30;
|
||
break;
|
||
case PIC_2560x1440: //360W
|
||
case PIC_2688x1520: //400W
|
||
h265_cbr.bit_rate = (1024 * 3 * framerate)/30;
|
||
break;
|
||
case PIC_2880x1620: //460W
|
||
case PIC_2560x1920: //500W
|
||
case PIC_2592x1944: //500W
|
||
case PIC_2688x1944: //520W
|
||
case PIC_3072x1728: //530W
|
||
h265_cbr.bit_rate = (1024 * 4 * framerate)/30;
|
||
break;
|
||
case PIC_3840x2160: //800W
|
||
h265_cbr.bit_rate = (1024 * 8 * framerate)/30;
|
||
break;
|
||
default : //other small resolution
|
||
h265_cbr.bit_rate = 1024 * 2;
|
||
break;
|
||
}
|
||
memcpy(&venc_attr.rc_attr.h265_cbr, &h265_cbr, sizeof(xmedia_venc_h265_cbr));
|
||
} else if (VENC_RC_MODE_H265FIXQP == chn_param->rc_mode) {
|
||
xmedia_venc_h265_fixqp h265_fix_qp;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_H265FIXQP;
|
||
h265_fix_qp.gop = 30;
|
||
h265_fix_qp.src_frame_rate = chn_param->src_frame_rate;
|
||
h265_fix_qp.dst_frame_rate = chn_param->dst_frame_rate;
|
||
h265_fix_qp.i_qp = 25;
|
||
h265_fix_qp.p_qp = 30;
|
||
h265_fix_qp.b_qp = 32;
|
||
memcpy(&venc_attr.rc_attr.h265_fixqp, &h265_fix_qp, sizeof(xmedia_venc_h265_fixqp));
|
||
} else if (VENC_RC_MODE_H265VBR == chn_param->rc_mode) {
|
||
xmedia_venc_h265_vbr h265_vbr;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_H265VBR;
|
||
h265_vbr.gop = gop;
|
||
h265_vbr.stat_time = stat_time;
|
||
h265_vbr.src_frame_rate = chn_param->src_frame_rate;
|
||
h265_vbr.dst_frame_rate = chn_param->dst_frame_rate;
|
||
switch (pic_size) {
|
||
case PIC_VGA:
|
||
case PIC_720P:
|
||
h265_vbr.max_bit_rate = (1024 * 1 * framerate)/30;
|
||
break;
|
||
case PIC_1080P:
|
||
case PIC_2304x1296:
|
||
h265_vbr.max_bit_rate = (1024 * 2 * framerate)/30;
|
||
break;
|
||
case PIC_2560x1440:
|
||
case PIC_2688x1520:
|
||
h265_vbr.max_bit_rate = (1024 * 3 * framerate)/30;
|
||
break;
|
||
case PIC_2880x1620:
|
||
case PIC_2560x1920:
|
||
case PIC_2592x1944:
|
||
case PIC_2688x1944:
|
||
case PIC_3072x1728:
|
||
h265_vbr.max_bit_rate = (1024 * 4 * framerate)/30;
|
||
break;
|
||
case PIC_3840x2160:
|
||
h265_vbr.max_bit_rate = (1024 * 8 * framerate)/30;
|
||
break;
|
||
default :
|
||
h265_vbr.max_bit_rate = 1024 * 2;
|
||
break;
|
||
}
|
||
memcpy(&venc_attr.rc_attr.h265_vbr, &h265_vbr, sizeof(xmedia_venc_h265_vbr));
|
||
} else if (VENC_RC_MODE_H265AVBR == chn_param->rc_mode) {
|
||
xmedia_venc_h265_avbr h265_avbr;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_H265AVBR;
|
||
h265_avbr.gop = gop;
|
||
h265_avbr.stat_time = stat_time;
|
||
h265_avbr.src_frame_rate = chn_param->src_frame_rate;
|
||
h265_avbr.dst_frame_rate = chn_param->dst_frame_rate;
|
||
switch (pic_size) {
|
||
case PIC_VGA:
|
||
case PIC_720P:
|
||
h265_avbr.max_bit_rate = (1024 * 1 * framerate)/30;
|
||
break;
|
||
case PIC_1080P:
|
||
case PIC_2304x1296:
|
||
h265_avbr.max_bit_rate = (1024 * 2 * framerate)/30;
|
||
break;
|
||
case PIC_2560x1440:
|
||
case PIC_2688x1520:
|
||
h265_avbr.max_bit_rate = (1024 * 3 * framerate)/30;
|
||
break;
|
||
case PIC_2880x1620:
|
||
case PIC_2560x1920:
|
||
case PIC_2592x1944:
|
||
case PIC_2688x1944:
|
||
case PIC_3072x1728:
|
||
h265_avbr.max_bit_rate = (1024 * 4 * framerate)/30;
|
||
break;
|
||
case PIC_3840x2160:
|
||
h265_avbr.max_bit_rate = (1024 * 8 * framerate)/30;
|
||
break;
|
||
default :
|
||
h265_avbr.max_bit_rate = 1024 * 2;
|
||
break;
|
||
}
|
||
memcpy(&venc_attr.rc_attr.h265_avbr, &h265_avbr, sizeof(xmedia_venc_h265_avbr));
|
||
}else if (VENC_RC_MODE_H265QPMAP == chn_param->rc_mode) {
|
||
xmedia_venc_h265_qpmap h265_qpmap;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_H265QPMAP;
|
||
h265_qpmap.gop = gop;
|
||
h265_qpmap.stat_time = stat_time;
|
||
h265_qpmap.src_frame_rate = chn_param->src_frame_rate;
|
||
h265_qpmap.dst_frame_rate = chn_param->dst_frame_rate;
|
||
memcpy(&venc_attr.rc_attr.h265_qpmap, &h265_qpmap, sizeof(xmedia_venc_h265_qpmap));
|
||
} else {
|
||
SAMPLE_PRT("rc mode(%d) not support\n",chn_param->rc_mode);
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
venc_attr.venc_attr.h264e_attr.rcn_ref_share_buf = chn_param->rcn_ref_share_buf;
|
||
}
|
||
break;
|
||
case PT_H264: {
|
||
if (VENC_RC_MODE_H264CBR == chn_param->rc_mode) {
|
||
xmedia_venc_h264_cbr h264_cbr;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_H264CBR;
|
||
h264_cbr.gop = gop; /*the interval of IFrame*/
|
||
h264_cbr.stat_time = stat_time; /* stream rate statics time(s) */
|
||
h264_cbr.src_frame_rate = chn_param->src_frame_rate; /* input (vi) frame rate */
|
||
h264_cbr.dst_frame_rate = chn_param->dst_frame_rate; /* target frame rate */
|
||
|
||
switch (pic_size) {
|
||
case PIC_VGA:
|
||
case PIC_720P:
|
||
h264_cbr.bit_rate = (1024 * 1 * framerate)/30;
|
||
break;
|
||
case PIC_1080P:
|
||
case PIC_2304x1296:
|
||
h264_cbr.bit_rate = (1024 * 2 * framerate)/30;
|
||
break;
|
||
case PIC_2560x1440:
|
||
case PIC_2688x1520:
|
||
h264_cbr.bit_rate = (1024 * 3 * framerate)/30;
|
||
break;
|
||
case PIC_2880x1620:
|
||
case PIC_2560x1920:
|
||
case PIC_2592x1944:
|
||
case PIC_2688x1944:
|
||
case PIC_3072x1728:
|
||
h264_cbr.bit_rate = (1024 * 4 * framerate)/30;
|
||
break;
|
||
case PIC_3840x2160:
|
||
h264_cbr.bit_rate = (1024 * 8 * framerate)/30;
|
||
break;
|
||
default :
|
||
h264_cbr.bit_rate = 1024 * 2;
|
||
break;
|
||
}
|
||
|
||
memcpy(&venc_attr.rc_attr.h264_cbr, &h264_cbr, sizeof(xmedia_venc_h264_cbr));
|
||
} else if (VENC_RC_MODE_H264FIXQP == chn_param->rc_mode) {
|
||
xmedia_venc_h264_fixqp h264_fixqp;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_H264FIXQP;
|
||
h264_fixqp.gop = 30;
|
||
h264_fixqp.src_frame_rate = chn_param->src_frame_rate;
|
||
h264_fixqp.dst_frame_rate = chn_param->dst_frame_rate;
|
||
h264_fixqp.i_qp = 25;
|
||
h264_fixqp.p_qp = 30;
|
||
h264_fixqp.b_qp = 32;
|
||
memcpy(&venc_attr.rc_attr.h264_fixqp, &h264_fixqp, sizeof(xmedia_venc_h264_fixqp));
|
||
} else if (VENC_RC_MODE_H264VBR == chn_param->rc_mode) {
|
||
xmedia_venc_h264_vbr h264_vbr;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_H264VBR;
|
||
h264_vbr.gop = gop;
|
||
h264_vbr.stat_time = stat_time;
|
||
h264_vbr.src_frame_rate = chn_param->src_frame_rate;
|
||
h264_vbr.dst_frame_rate = chn_param->dst_frame_rate;
|
||
switch (pic_size) {
|
||
case PIC_VGA:
|
||
case PIC_720P:
|
||
h264_vbr.max_bit_rate = (1024 * 1 * framerate)/30;
|
||
break;
|
||
case PIC_1080P:
|
||
case PIC_2304x1296:
|
||
h264_vbr.max_bit_rate = (1024 * 2 * framerate)/30;
|
||
break;
|
||
case PIC_2560x1440:
|
||
case PIC_2688x1520:
|
||
h264_vbr.max_bit_rate = (1024 * 3 * framerate)/30;
|
||
break;
|
||
case PIC_2880x1620:
|
||
case PIC_2560x1920:
|
||
case PIC_2592x1944:
|
||
case PIC_2688x1944:
|
||
case PIC_3072x1728:
|
||
h264_vbr.max_bit_rate = (1024 * 4 * framerate)/30;
|
||
break;
|
||
case PIC_3840x2160:
|
||
h264_vbr.max_bit_rate = (1024 * 8 * framerate)/30;
|
||
break;
|
||
default :
|
||
h264_vbr.max_bit_rate = 1024 * 2;
|
||
break;
|
||
}
|
||
memcpy(&venc_attr.rc_attr.h264_vbr, &h264_vbr, sizeof(xmedia_venc_h264_vbr));
|
||
} else if (VENC_RC_MODE_H264AVBR == chn_param->rc_mode) {
|
||
xmedia_venc_h264_avbr h264_avbr;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_H264AVBR;
|
||
h264_avbr.gop = gop;
|
||
h264_avbr.stat_time = stat_time;
|
||
h264_avbr.src_frame_rate = chn_param->src_frame_rate;
|
||
h264_avbr.dst_frame_rate = chn_param->dst_frame_rate;
|
||
switch (pic_size) {
|
||
case PIC_VGA:
|
||
case PIC_720P:
|
||
h264_avbr.max_bit_rate = (1024 * 1 * framerate)/30;
|
||
break;
|
||
case PIC_1080P:
|
||
case PIC_2304x1296:
|
||
h264_avbr.max_bit_rate = (1024 * 2 * framerate)/30;
|
||
break;
|
||
case PIC_2560x1440:
|
||
case PIC_2688x1520:
|
||
h264_avbr.max_bit_rate = (1024 * 3 * framerate)/30;
|
||
break;
|
||
case PIC_2880x1620:
|
||
case PIC_2560x1920:
|
||
case PIC_2592x1944:
|
||
case PIC_2688x1944:
|
||
case PIC_3072x1728:
|
||
h264_avbr.max_bit_rate = (1024 * 4 * framerate)/30;
|
||
break;
|
||
case PIC_3840x2160:
|
||
h264_avbr.max_bit_rate = (1024 * 8 * framerate)/30;
|
||
break;
|
||
default :
|
||
h264_avbr.max_bit_rate = 1024 * 2;
|
||
break;
|
||
}
|
||
memcpy(&venc_attr.rc_attr.h264_avbr, &h264_avbr, sizeof(xmedia_venc_h264_avbr));
|
||
} else if (VENC_RC_MODE_H264QPMAP == chn_param->rc_mode) {
|
||
xmedia_venc_h264_qpmap h264_qpmap;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_H264QPMAP;
|
||
h264_qpmap.gop = gop;
|
||
h264_qpmap.stat_time = stat_time;
|
||
h264_qpmap.src_frame_rate = chn_param->src_frame_rate;
|
||
h264_qpmap.dst_frame_rate = chn_param->dst_frame_rate;
|
||
memcpy(&venc_attr.rc_attr.h264_qpmap, &h264_qpmap, sizeof(xmedia_venc_h264_qpmap));
|
||
} else {
|
||
SAMPLE_PRT("rc mode(%d) not support\n",chn_param->rc_mode);
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
venc_attr.venc_attr.h264e_attr.rcn_ref_share_buf = chn_param->rcn_ref_share_buf;
|
||
}
|
||
break;
|
||
case PT_MJPEG: {
|
||
if (VENC_RC_MODE_MJPEGFIXQP == chn_param->rc_mode) {
|
||
xmedia_venc_mjpeg_fixqp mjpege_fixqp;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_MJPEGFIXQP;
|
||
mjpege_fixqp.q_factor = 95;
|
||
mjpege_fixqp.src_frame_rate = chn_param->src_frame_rate;
|
||
mjpege_fixqp.dst_frame_rate = chn_param->dst_frame_rate;
|
||
|
||
memcpy(&venc_attr.rc_attr.mjpeg_fixqp, &mjpege_fixqp,sizeof(xmedia_venc_mjpeg_fixqp));
|
||
} else if (VENC_RC_MODE_MJPEGCBR == chn_param->rc_mode) {
|
||
xmedia_venc_mjpeg_cbr mjpeg_cbr;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_MJPEGCBR;
|
||
mjpeg_cbr.stat_time = stat_time;
|
||
mjpeg_cbr.src_frame_rate = chn_param->src_frame_rate;
|
||
mjpeg_cbr.dst_frame_rate = chn_param->dst_frame_rate;
|
||
switch (pic_size) {
|
||
case PIC_VGA:
|
||
mjpeg_cbr.bit_rate = (1024 * 4 * framerate)/30;
|
||
break;
|
||
case PIC_720P:
|
||
mjpeg_cbr.bit_rate = (1024 * 6 * framerate)/30;
|
||
break;
|
||
case PIC_1080P:
|
||
mjpeg_cbr.bit_rate = (1024 * 10 * framerate)/30;
|
||
break;
|
||
case PIC_2560x1440:
|
||
case PIC_2560x1920:
|
||
mjpeg_cbr.bit_rate = (1024 * 17 * framerate)/30;
|
||
break;
|
||
case PIC_2688x1520:
|
||
case PIC_2592x1944:
|
||
case PIC_2688x1944:
|
||
mjpeg_cbr.bit_rate = (1024 * 23 * framerate)/30;
|
||
break;
|
||
case PIC_3840x2160:
|
||
mjpeg_cbr.bit_rate = (1024 * 30 * framerate)/30;
|
||
break;
|
||
case PIC_4000x3000:
|
||
mjpeg_cbr.bit_rate = (1024 * 35 * framerate)/30;
|
||
break;
|
||
case PIC_7680x4320:
|
||
mjpeg_cbr.bit_rate = (1024 * 40 * framerate)/30;
|
||
break;
|
||
default :
|
||
mjpeg_cbr.bit_rate = (1024 * 20 * framerate)/30;
|
||
break;
|
||
}
|
||
|
||
memcpy(&venc_attr.rc_attr.mjpeg_cbr, &mjpeg_cbr,sizeof(xmedia_venc_mjpeg_cbr));
|
||
} else if (VENC_RC_MODE_MJPEGVBR == chn_param->rc_mode) {
|
||
xmedia_venc_mjpeg_vbr mjpeg_vbr;
|
||
|
||
venc_attr.rc_attr.rc_mode = VENC_RC_MODE_MJPEGVBR;
|
||
mjpeg_vbr.stat_time = stat_time;
|
||
mjpeg_vbr.src_frame_rate = chn_param->src_frame_rate;
|
||
mjpeg_vbr.dst_frame_rate = 5;
|
||
|
||
switch (pic_size) {
|
||
case PIC_VGA:
|
||
mjpeg_vbr.max_bit_rate = (1024 * 4 * framerate)/30;
|
||
break;
|
||
case PIC_720P:
|
||
mjpeg_vbr.max_bit_rate = (1024 * 6 * framerate)/30;
|
||
break;
|
||
case PIC_1080P:
|
||
mjpeg_vbr.max_bit_rate = (1024 * 10 * framerate)/30;
|
||
break;
|
||
case PIC_2560x1440:
|
||
case PIC_2560x1920:
|
||
mjpeg_vbr.max_bit_rate = (1024 * 17 * framerate)/30;
|
||
break;
|
||
case PIC_2688x1520:
|
||
case PIC_2592x1944:
|
||
case PIC_2688x1944:
|
||
mjpeg_vbr.max_bit_rate = (1024 * 23 * framerate)/30;
|
||
break;
|
||
case PIC_3840x2160:
|
||
mjpeg_vbr.max_bit_rate = (1024 * 30 * framerate)/30;
|
||
break;
|
||
case PIC_4000x3000:
|
||
mjpeg_vbr.max_bit_rate = (1024 * 35 * framerate)/30;
|
||
break;
|
||
case PIC_7680x4320:
|
||
mjpeg_vbr.max_bit_rate = (1024 * 40 * framerate)/30;
|
||
break;
|
||
default :
|
||
mjpeg_vbr.max_bit_rate = (1024 * 20 * framerate)/30;
|
||
break;
|
||
}
|
||
|
||
memcpy(&venc_attr.rc_attr.mjpeg_vbr, &mjpeg_vbr,sizeof(xmedia_venc_mjpeg_vbr));
|
||
} else {
|
||
SAMPLE_PRT("cann't support other mode(%d) in this version!\n",chn_param->rc_mode);
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PT_JPEG:
|
||
memcpy(&venc_attr.venc_attr.jpege_attr, &chn_param->jpeg_attr, sizeof(xmedia_venc_attr_jpeg));
|
||
if (chn_param->jpeg_slice.slice_enable) {
|
||
venc_attr.venc_attr.by_frame = chn_param->jpeg_slice.by_frame;
|
||
}
|
||
break;
|
||
default:
|
||
SAMPLE_PRT("not support the payload type !\n");
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
|
||
if (PT_MJPEG == chn_param->payload_type || PT_JPEG == chn_param->payload_type ) {
|
||
venc_attr.gop_attr.gop_mode = VENC_GOPMODE_NORMALP;
|
||
venc_attr.gop_attr.normal_p.ip_qp_delta = 0;
|
||
} else {
|
||
memcpy(&venc_attr.gop_attr, &chn_param->venc_gop_attr, sizeof(xmedia_venc_gop_attr));
|
||
|
||
if ((VENC_RC_MODE_H264QPMAP == venc_attr.rc_attr.rc_mode)||(VENC_RC_MODE_H265QPMAP == venc_attr.rc_attr.rc_mode)) {
|
||
if (VENC_GOPMODE_ADVSMARTP == chn_param->venc_gop_attr.gop_mode) {
|
||
venc_attr.gop_attr.gop_mode = VENC_GOPMODE_SMARTP;
|
||
|
||
SAMPLE_PRT("advsmartp not support QPMAP, so change gopmode to smartp!\n");
|
||
}
|
||
}
|
||
}
|
||
|
||
CHECK_RET(xmedia_venc_create_chn(chn_param->venc_chn, &venc_attr), "create venc chn");
|
||
|
||
CHECK_RET(sample_comm_venc_set_rc_param(chn_param->venc_chn), "reset reencode times");
|
||
|
||
#if 0
|
||
// For improve H.264 performance
|
||
xmedia_venc_search_window search_window;
|
||
search_window.ime_search = VENC_IME_SEARCH_WINDOW_W8_H8;
|
||
search_window.pme_search = VENC_PME_SEARCH_WINDOW_128_96 ;
|
||
CHECK_RET(xmedia_venc_set_search_window(chn_param->venc_chn, &search_window), "set search window");
|
||
#endif
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_set_fps_to_stream(sample_venc_chn_info *chn_param)
|
||
{
|
||
xmedia_venc_h264_vui h264_vui = {0};
|
||
xmedia_venc_h265_vui h265_vui = {0};
|
||
|
||
if ((chn_param->venc_en == XMEDIA_TRUE) && (chn_param->vui_info.vui_en == XMEDIA_TRUE)) {
|
||
if (chn_param->payload_type == PT_H264) {
|
||
CHECK_RET(xmedia_venc_get_h264_vui(chn_param->venc_chn, &h264_vui), "get h264 vui");
|
||
h264_vui.vui_time_info.timing_info_present_flag = 1;
|
||
h264_vui.vui_time_info.num_units_in_tick = 1;
|
||
h264_vui.vui_time_info.time_scale = chn_param->vui_info.stream_display_fps * 2;
|
||
CHECK_RET(xmedia_venc_set_h264_vui(chn_param->venc_chn, &h264_vui), "set h264 vui");
|
||
} else if (chn_param->payload_type == PT_H265) {
|
||
CHECK_RET(xmedia_venc_get_h265_vui(chn_param->venc_chn, &h265_vui), "get h265 vui");
|
||
h265_vui.vui_time_info.timing_info_present_flag = 1;
|
||
h265_vui.vui_time_info.num_units_in_tick = 1;
|
||
h265_vui.vui_time_info.time_scale = chn_param->vui_info.stream_display_fps;
|
||
CHECK_RET(xmedia_venc_set_h265_vui(chn_param->venc_chn, &h265_vui), "set h265 vui");
|
||
}
|
||
}
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_destory_chn(xmedia_s32 venc_chn)
|
||
{
|
||
CHECK_RET(xmedia_venc_destroy_chn(venc_chn), "destroy venc chn");
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_start(sample_venc_config *venc_cfg)
|
||
{
|
||
xmedia_s32 i;
|
||
sample_venc_chn_info *chn_param = NULL;
|
||
|
||
for (i = 0; i < VENC_MAX_CHN_NUM; i++) {
|
||
chn_param = &venc_cfg->chn_info[i];
|
||
|
||
if (chn_param->venc_en == XMEDIA_FALSE) {
|
||
continue;
|
||
}
|
||
|
||
CHECK_RET(sample_comm_venc_create_chn(chn_param), "create venc chn");
|
||
if (chn_param->payload_type == PT_JPEG) {
|
||
continue;
|
||
}
|
||
|
||
sample_comm_venc_set_fps_to_stream(chn_param);
|
||
|
||
CHECK_RET(sample_comm_venc_start_chn(chn_param->venc_chn), "start venc chn");
|
||
}
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_stop(sample_venc_config *venc_cfg)
|
||
{
|
||
xmedia_s32 i;
|
||
sample_venc_chn_info *chn_param = NULL;
|
||
|
||
for (i = 0; i < VENC_MAX_CHN_NUM; i++) {
|
||
chn_param = &venc_cfg->chn_info[i];
|
||
|
||
if (chn_param->venc_en == XMEDIA_FALSE) {
|
||
continue;
|
||
}
|
||
|
||
CHECK_RET(sample_comm_venc_stop_chn(chn_param->venc_chn), "stop venc chn");
|
||
|
||
CHECK_RET(sample_comm_venc_destory_chn(chn_param->venc_chn), "destory venc chn");
|
||
}
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_void sample_venc_save_one_frame_nv21(FILE * fp,xmedia_u8 * vir_y, xmedia_u8 * vir_c,
|
||
xmedia_u32 width, xmedia_u32 height, xmedia_u32 stride)
|
||
{
|
||
xmedia_u8 * dst;
|
||
xmedia_u32 row;
|
||
|
||
dst = vir_y;
|
||
for(row = 0; row < height; row++) {
|
||
fwrite( dst, width, 1, fp );
|
||
dst += stride;
|
||
}
|
||
|
||
dst = vir_c;
|
||
for(row = 0; row < height/2; row++) {
|
||
fwrite(dst, width, 1, fp);
|
||
dst += stride;
|
||
}
|
||
}
|
||
|
||
/**** User send yuv + venc only start ****/
|
||
xmedia_void sample_venc_read_one_frame_nv21(FILE * fp,xmedia_u8 * vir_y, xmedia_u8 * vir_c,
|
||
xmedia_u32 width, xmedia_u32 height, xmedia_u32 stride)
|
||
{
|
||
xmedia_u8 * dst;
|
||
xmedia_u32 row;
|
||
|
||
dst = vir_y;
|
||
for(row = 0; row < height; row++) {
|
||
fread( dst, width, 1, fp );
|
||
dst += stride;
|
||
}
|
||
|
||
dst = vir_c;
|
||
for(row = 0; row < height/2; row++) {
|
||
fread(dst, width, 1, fp);
|
||
dst += stride;
|
||
}
|
||
}
|
||
|
||
xmedia_void sample_venc_read_one_frame_sp422_semi(FILE * fp, xmedia_u8 * vir_y, xmedia_u8 * vir_c,
|
||
xmedia_u32 width, xmedia_u32 height, xmedia_u32 stride)
|
||
{
|
||
xmedia_u8 * dst;
|
||
xmedia_u32 row;
|
||
|
||
dst = vir_y;
|
||
for(row = 0; row < height; row++) {
|
||
fread( dst, width, 1, fp );
|
||
dst += stride;
|
||
}
|
||
|
||
dst = vir_c;
|
||
for(row = 0; row < height; row++) {
|
||
fread(dst, width, 1, fp);
|
||
dst += stride;
|
||
}
|
||
}
|
||
|
||
xmedia_void *sample_comm_venc_user_send_thread(void *data)
|
||
{
|
||
char a;
|
||
xmedia_u8 i;
|
||
xmedia_u8 j = 0;
|
||
xmedia_s32 ret;
|
||
xmedia_u32 cnt = 0;
|
||
xmedia_u32 vir_addr_y, vir_addr_c;
|
||
xmedia_u32 try_send_cnt = 0;
|
||
xmedia_u32 max_cnt = 0xffffffff;
|
||
sample_venc_mem_buf_info mem = {0};
|
||
xmedia_video_frame_info video_info;
|
||
sample_venc_yuv_thread_para* venc_user_attr;
|
||
xmedia_u32 pool = VB_INVALID_POOLID;
|
||
xmedia_video_private_info vb_info = {0};
|
||
xmedia_u32 luma_size = 0;
|
||
// xmedia_u32 chrm_size = 0;
|
||
xmedia_u32 pic_luma_stride;
|
||
xmedia_u32 align_pic_height,align_pic_width;
|
||
xmedia_u32 size = 0;
|
||
xmedia_u32 is_save = XMEDIA_FALSE;
|
||
FILE *input_yuv = XMEDIA_NULL;
|
||
|
||
venc_user_attr = (sample_venc_yuv_thread_para *)data;
|
||
|
||
if(venc_user_attr == XMEDIA_NULL) {
|
||
return XMEDIA_NULL;
|
||
}
|
||
pool = venc_user_attr->pool;
|
||
|
||
align_pic_height = ((venc_user_attr->user_height + 15) >> 4) << 4;
|
||
align_pic_width = ((venc_user_attr->user_width + 15) >> 4) << 4;
|
||
pic_luma_stride = ((venc_user_attr->user_width + 15) >> 4) << 4;
|
||
|
||
|
||
if(venc_user_attr->user_pixel_format == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422 ||
|
||
venc_user_attr->user_pixel_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) {
|
||
luma_size = (pic_luma_stride * venc_user_attr->user_height);
|
||
// chrm_size = luma_size >> 1;
|
||
size = align_pic_width * align_pic_height * 2;
|
||
} else if (venc_user_attr->user_pixel_format == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420 ||
|
||
venc_user_attr->user_pixel_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) {
|
||
luma_size = (pic_luma_stride * venc_user_attr->user_height);
|
||
// chrm_size = luma_size >> 2;
|
||
size = align_pic_width * align_pic_height * 3 / 2;
|
||
} else if (venc_user_attr->user_pixel_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
|
||
luma_size = (pic_luma_stride * venc_user_attr->user_height);
|
||
size = align_pic_width * align_pic_height;
|
||
}
|
||
|
||
mem.pool = pool;
|
||
|
||
max_cnt = venc_user_attr->max_send_yuv_cnt ? venc_user_attr->max_send_yuv_cnt : 300;
|
||
input_yuv = venc_user_attr->input_yuv[j];
|
||
if (venc_user_attr->user_send_yuv_delay_ms > 0) {
|
||
printf("u32UserSendYuvDleayInMs:%u\n", venc_user_attr->user_send_yuv_delay_ms);
|
||
usleep(venc_user_attr->user_send_yuv_delay_ms * 1000);
|
||
}
|
||
while((XMEDIA_TRUE == g_user_start) && (cnt < max_cnt)) {
|
||
fread((void *)(&a), 1, 1, input_yuv);
|
||
if (0 != feof(input_yuv)) {
|
||
if (venc_user_attr->yuv_num > 1) {
|
||
j++;
|
||
if (j >= venc_user_attr->max_send_yuv_cnt) {
|
||
break;
|
||
}
|
||
input_yuv = venc_user_attr->input_yuv[j];
|
||
} else {
|
||
fseek(input_yuv, 0, SEEK_SET);
|
||
}
|
||
} else {
|
||
fseek(input_yuv, -1, SEEK_CUR);
|
||
}
|
||
|
||
while ((mem.block = xmedia_vb_get_block(mem.pool, size, XMEDIA_NULL)) == VB_INVALID_HANDLE) {
|
||
usleep(500 * 1000);
|
||
}
|
||
|
||
mem.phy_addr = xmedia_vb_handle_to_phy_addr(mem.block);
|
||
mem.vir_addr = (xmedia_u8 *)xmedia_mmz_map(mem.phy_addr, size, 0);
|
||
if (mem.vir_addr == NULL) {
|
||
printf("mem dev may not open\n");
|
||
xmedia_vb_release_block(mem.block);
|
||
return XMEDIA_NULL;
|
||
}
|
||
ret = xmedia_vb_get_supplement_info(mem.block, &vb_info);
|
||
if(ret != XMEDIA_SUCCESS) {
|
||
printf("xmedia_vb_get_supplement_info ERROR\n");
|
||
xmedia_vb_release_block(mem.block);
|
||
return XMEDIA_NULL;
|
||
}
|
||
|
||
memset(&video_info.frame, 0, sizeof(xmedia_video_frame));
|
||
video_info.frame.dynamic_range = XMEDIA_VIDEO_DYNAMIC_RANGE_SDR;
|
||
video_info.frame.color_info.color_gamut = XMEDIA_VIDEO_COLOR_GAMUT_BT709;
|
||
video_info.frame.addr.y_phy_addr = mem.phy_addr;
|
||
video_info.frame.addr.c_phy_addr = video_info.frame.addr.y_phy_addr + luma_size;
|
||
// video_info.frame.phy_addr_cr = frm_info.frame.phy_addr[1] + chrm_size;
|
||
|
||
vir_addr_y = (xmedia_u64)(xmedia_ulong)mem.vir_addr;
|
||
vir_addr_c = (xmedia_u64)(xmedia_ulong)(vir_addr_y + luma_size);
|
||
// video_info.frame.vir_addr_cr = (xmedia_u64)(xmedia_ulong)(vir_addr_c + chrm_size);
|
||
|
||
video_info.frame.width = venc_user_attr->user_width;
|
||
video_info.frame.height = venc_user_attr->user_height;
|
||
|
||
video_info.frame.stride.y_stride = pic_luma_stride;
|
||
video_info.frame.stride.c_stride = pic_luma_stride;
|
||
// video_info.frame.stride_cr = pic_luma_stride;
|
||
|
||
video_info.frame.pts = (cnt * 40);
|
||
video_info.frame.index = (cnt * 2);
|
||
cnt++;
|
||
video_info.frame.priv_info.isp_info_phy_addr = vb_info.isp_info_phy_addr;
|
||
video_info.frame.priv_info.isp_info_vir_addr = vb_info.isp_info_vir_addr;
|
||
video_info.frame.pixel_fmt = venc_user_attr->user_pixel_format;
|
||
|
||
if (venc_user_attr->user_pixel_format == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422 ||
|
||
venc_user_attr->user_pixel_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) {
|
||
sample_venc_read_one_frame_sp422_semi(input_yuv, (xmedia_u8 *)(xmedia_ulong)vir_addr_y,
|
||
(xmedia_u8 *)(xmedia_ulong)vir_addr_c,
|
||
video_info.frame.width, video_info.frame.height, video_info.frame.stride.y_stride);
|
||
} else if (venc_user_attr->user_pixel_format == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420 ||
|
||
venc_user_attr->user_pixel_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) {
|
||
sample_venc_read_one_frame_nv21(input_yuv, (xmedia_u8 *)(xmedia_ulong)vir_addr_y,
|
||
(xmedia_u8 *)(xmedia_ulong)vir_addr_c,
|
||
video_info.frame.width, video_info.frame.height, video_info.frame.stride.y_stride);
|
||
}
|
||
|
||
mem.pool_id = xmedia_vb_handle_to_pool_id(mem.block);
|
||
video_info.pool_id = mem.pool_id;
|
||
|
||
video_info.frame.compress_mode = venc_user_attr->user_compress_mode;
|
||
video_info.frame.video_fmt = venc_user_attr->user_video_format;
|
||
if (is_save == XMEDIA_TRUE) {
|
||
FILE *tmp = fopen("./tmp.yuv", "wb");
|
||
sample_venc_save_one_frame_nv21(tmp, (xmedia_u8 *)(xmedia_ulong)vir_addr_y,
|
||
(xmedia_u8 *)(xmedia_ulong)vir_addr_c,
|
||
video_info.frame.width, video_info.frame.height, video_info.frame.stride.y_stride);
|
||
is_save = XMEDIA_FALSE;
|
||
fclose(tmp);
|
||
}
|
||
printf("%s,%d,SendPic, MaxCnt:%d, curcnt:%d\n", __FUNCTION__, __LINE__, max_cnt, cnt);
|
||
for (i = 0; i < venc_user_attr->h265e_cnt; i++) {
|
||
try_send_cnt = 0;
|
||
while (xmedia_venc_send_frame(venc_user_attr->h265e_chnl[i], &video_info, 0) != 0 &&
|
||
(g_user_start == XMEDIA_TRUE) && try_send_cnt < 2) { // 2: timeout count
|
||
try_send_cnt++;
|
||
usleep(500 * 1000); //timeout
|
||
printf("[%d] h265 xmedia_venc_send_frame ERROR === u32TrySendCnt:%d, MaxCnt:cnt:%d:%d\n",
|
||
__LINE__, try_send_cnt,max_cnt,cnt);
|
||
}
|
||
}
|
||
|
||
for (i = 0; i < venc_user_attr->h264e_cnt; i++) {
|
||
try_send_cnt = 0;
|
||
while (xmedia_venc_send_frame(venc_user_attr->h264e_chnl[i], &video_info, 0) != 0 &&
|
||
(g_user_start == XMEDIA_TRUE) && try_send_cnt < 2) { // 2: timeout count
|
||
try_send_cnt++;
|
||
usleep(500 * 1000); //timeout
|
||
printf("[%d] h264 xmedia_venc_send_frame ERROR === u32TrySendCnt:%d, MaxCnt:cnt:%d:%d\n",
|
||
__LINE__, try_send_cnt,max_cnt,cnt);
|
||
}
|
||
}
|
||
|
||
for (i = 0; i < venc_user_attr->mjpeg_cnt; i++) {
|
||
try_send_cnt = 0;
|
||
while(xmedia_venc_send_frame(venc_user_attr->mjpeg_chnl[i], &video_info, 0) != 0 &&
|
||
(g_user_start == XMEDIA_TRUE) && try_send_cnt < 2) {
|
||
try_send_cnt++;
|
||
usleep(500 * 1000); //timeout
|
||
printf("[%d] MJPEG xmedia_venc_send_frame ERROR === u32TrySendCnt:%d, MaxCnt : cnt:%d : %d\n",
|
||
__LINE__, try_send_cnt,max_cnt,cnt);
|
||
}
|
||
}
|
||
|
||
for (i = 0; i < venc_user_attr->jpege_cnt; i++) {
|
||
try_send_cnt = 0;
|
||
while ((xmedia_venc_send_frame(venc_user_attr->jpege_chnl[i], &video_info, 0) != 0) &&
|
||
(g_user_start == XMEDIA_TRUE) && (try_send_cnt < 2)) {
|
||
try_send_cnt++;
|
||
usleep(500 * 1000); //timeout
|
||
printf("[%d] JPEG xmedia_venc_send_frame ERROR === TrySendCnt:%d, MaxCnt:cnt:%d:%d\n",
|
||
__LINE__, try_send_cnt,max_cnt,cnt);
|
||
}
|
||
}
|
||
|
||
xmedia_mmz_unmap(mem.vir_addr);
|
||
xmedia_vb_release_block(mem.block);
|
||
}
|
||
printf("Send over, cnt:%d/%d\n", cnt, max_cnt);
|
||
|
||
return XMEDIA_NULL;
|
||
}
|
||
/**** User send yuv + venc only end ****/
|
||
|
||
xmedia_s32 app_liveserver_send_video_data(xcam_handle venc_handle, xmedia_payload_type payload_type, xmedia_venc_stream *stream)
|
||
{
|
||
xcam_livestream_rtsp_data rtsp_data;
|
||
xcam_bool is_key_frame = XCAM_FALSE;
|
||
xmedia_venc_data_type data_type;
|
||
xmedia_s32 ret;
|
||
xmedia_u64 cur_pts = 0;
|
||
|
||
if (xcam_liveserver_is_init() == XCAM_FALSE) {
|
||
return XCAM_LIVESERVER_ERR_NOT_INIT;
|
||
}
|
||
|
||
//data_type = stream->pack[stream->pack_count - 1].data_type;
|
||
data_type = stream->pack[0].data_type;
|
||
if (payload_type == PT_H265) {
|
||
#if 1
|
||
is_key_frame = ((data_type.h265e_type == H265E_NALU_VPS)
|
||
|| (data_type.h265e_type == H265E_NALU_ISLICE)) ? XMEDIA_TRUE : XMEDIA_FALSE;
|
||
#else
|
||
is_key_frame = ((0x00 == stream->pack[stream->pack_count - 1].vir_addr[0]) &&
|
||
(0x00 == stream->pack[stream->pack_count - 1].vir_addr[1]) &&
|
||
(0x01 == stream->pack[stream->pack_count - 1].vir_addr[2]) &&
|
||
(0x14 == ((stream->pack[stream->pack_count - 1].vir_addr[3] >> 0x01) & 0x3f)));
|
||
#endif
|
||
} else if (payload_type == PT_H264) {
|
||
is_key_frame = ((data_type.h264e_type == H264E_NALU_IDRSLICE)
|
||
|| (data_type.h264e_type == H264E_NALU_ISLICE)
|
||
|| (data_type.h264e_type == H264E_NALU_SPS)) ? XMEDIA_TRUE : XMEDIA_FALSE;
|
||
}
|
||
|
||
xmedia_sys_get_cur_pts(&cur_pts);
|
||
rtsp_data.pts_us = cur_pts;
|
||
rtsp_data.seq_num = stream->seq;
|
||
rtsp_data.is_key_frame = is_key_frame;
|
||
rtsp_data.block_cnt = stream->pack_count;
|
||
for (xcam_u32 idx = 0; idx < stream->pack_count; ++idx) {
|
||
rtsp_data.data_ptr[idx] = stream->pack[idx].vir_addr;
|
||
rtsp_data.data_len[idx] = stream->pack[idx].len;
|
||
}
|
||
|
||
ret = xcam_liveserver_send_video_data(venc_handle, &rtsp_data);
|
||
|
||
return ret;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_set_roi(xmedia_s32 venc_chn[], xmedia_s32 chn_cnt)
|
||
{
|
||
xmedia_u32 i;
|
||
xmedia_s32 ret;
|
||
xmedia_venc_roi_attr roi_attr;
|
||
|
||
for (i = 0;i < chn_cnt;i++) {
|
||
ret = xmedia_venc_get_roi_attr(venc_chn[i], 0, &roi_attr);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("get roi attr failed for %#x!\n", ret);
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
|
||
roi_attr.abs_qp = XMEDIA_TRUE;
|
||
roi_attr.enable = XMEDIA_TRUE;
|
||
roi_attr.qp = 20;
|
||
roi_attr.index = 0;
|
||
roi_attr.rect.x = 64;
|
||
roi_attr.rect.y = 64;
|
||
roi_attr.rect.height = 256;
|
||
roi_attr.rect.width = 256;
|
||
|
||
ret = xmedia_venc_set_roi_attr(venc_chn[i], &roi_attr);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("set Roi attr failed for %#x!\n", ret);
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
}
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_void* sample_comm_venc_get_stream_proc(xmedia_void *pData)
|
||
{
|
||
sample_venc_getstream_para *param = (sample_venc_getstream_para*)pData;
|
||
xmedia_s32 chn_cnt = param->cnt;
|
||
xmedia_s32 i;
|
||
xmedia_s32 ret = XMEDIA_FAILURE;
|
||
xmedia_venc_chn_attr venc_chn_attr;
|
||
xmedia_payload_type payload_type[VENC_MAX_CHN_NUM];
|
||
xmedia_char file_post_fix[VENC_MAX_CHN_NUM][10];
|
||
|
||
xmedia_char file_name[VENC_MAX_CHN_NUM][512];
|
||
xmedia_char file_path[128];
|
||
FILE *file_ptr[VENC_MAX_CHN_NUM];
|
||
|
||
struct timeval time_out;
|
||
xmedia_venc_stream venc_stream;
|
||
xmedia_venc_chn_status stat;
|
||
xmedia_u32 picture_cnt[VENC_MAX_CHN_NUM] = {0};
|
||
xmedia_u32 venc_mask = 0;
|
||
|
||
if (chn_cnt >= VENC_MAX_CHN_NUM) {
|
||
SAMPLE_PRT("input venc chn count invaild\n");
|
||
return XMEDIA_NULL;
|
||
}
|
||
|
||
memset(file_path, 0, 128);
|
||
snprintf(file_path, 128, "%s", param->save_path);
|
||
mkdir(file_path, S_IRWXU|S_IRWXG|S_IRWXO);
|
||
|
||
prctl(PR_SET_NAME, (unsigned long)(uintptr_t)"VencGetStream", 0, 0, 0);
|
||
|
||
for (i = 0; i < chn_cnt; ++i) {
|
||
if (param->venc_chn[i] < 0) {
|
||
continue;
|
||
}
|
||
|
||
ret = xmedia_venc_get_chn_attr(param->venc_chn[i], &venc_chn_attr);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("xmedia_venc_get_chn_attr chn[%d] failed with %#x!\n", param->venc_chn[i], ret);
|
||
return XMEDIA_NULL;
|
||
}
|
||
|
||
payload_type[i] = venc_chn_attr.venc_attr.en_type;
|
||
|
||
ret = sample_comm_venc_get_file_post_fix(payload_type[i], file_post_fix[i]);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("sample_comm_venc_get_file_post_fix [%d] failed with %#x!\n", payload_type[i], ret);
|
||
return XMEDIA_NULL;
|
||
}
|
||
|
||
if (param->save_stream == XMEDIA_TRUE) {
|
||
if (PT_JPEG != payload_type[i]) {
|
||
snprintf(file_name[i], 512, "%s/stream_chn%d%s", file_path, i, file_post_fix[i]);
|
||
file_ptr[i] = fopen(file_name[i], "wb");
|
||
if (!file_ptr[i]) {
|
||
SAMPLE_PRT("open file %s failed!\n", file_name[i]);
|
||
return XMEDIA_NULL;
|
||
}
|
||
chmod(file_name[i], S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||
} else if (param->save_jpeg) {
|
||
}
|
||
}
|
||
venc_mask |= 1 << param->venc_chn[i];
|
||
}
|
||
|
||
while (param->thread_start) {
|
||
time_out.tv_sec = 12;
|
||
time_out.tv_usec = 0;
|
||
ret = xmedia_venc_select(venc_mask, &time_out);
|
||
if (ret == XMEDIA_ERRCODE_INVALID_PARAM || ret == XMEDIA_FAILURE) {
|
||
SAMPLE_PRT("select err\n");
|
||
break;
|
||
} else if (ret == XMEDIA_ERRCODE_TIMEOUT) {
|
||
param->stream_timeout_cnt++;
|
||
SAMPLE_PRT("get venc stream time out, continue. \n");
|
||
usleep(100 * 1000);
|
||
continue;
|
||
}
|
||
|
||
for (i = 0; i < chn_cnt; ++i) {
|
||
if (param->venc_chn[i] < 0) {
|
||
continue;
|
||
}
|
||
|
||
ret = xmedia_venc_query_status(param->venc_chn[i], &stat);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("xmedia_venc_query_status chn[%d] failed with %#x!\n", i, ret);
|
||
break;
|
||
}
|
||
|
||
if (0 == stat.cur_packs) {
|
||
continue;
|
||
} else if ((param->save_jpeg != XMEDIA_TRUE) && (payload_type[i] == PT_JPEG)) {
|
||
continue;
|
||
}
|
||
|
||
memset(&venc_stream, 0, sizeof(venc_stream));
|
||
venc_stream.pack = (xmedia_venc_pack*)malloc(sizeof(xmedia_venc_pack) * stat.cur_packs);
|
||
if (XMEDIA_NULL == venc_stream.pack) {
|
||
SAMPLE_PRT("malloc stream pack failed!\n");
|
||
break;
|
||
}
|
||
|
||
venc_stream.pack_count = stat.cur_packs;
|
||
ret = xmedia_venc_get_stream(param->venc_chn[i], &venc_stream, -1);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
free(venc_stream.pack);
|
||
venc_stream.pack = XMEDIA_NULL;
|
||
xmedia_venc_release_stream(param->venc_chn[i], &venc_stream);
|
||
SAMPLE_PRT("xmedia_venc_get_stream failed with %#x!\n", ret);
|
||
break;
|
||
}
|
||
|
||
if ((param->save_jpeg == XMEDIA_TRUE) && (payload_type[i] == PT_JPEG)) {
|
||
snprintf(file_name[i], 512, "%s/snap%d_%d%s", file_path, i, picture_cnt[i], file_post_fix[i]);
|
||
file_ptr[i] = fopen(file_name[i], "wb");
|
||
if (!file_ptr[i]) {
|
||
SAMPLE_PRT("open file err!\n");
|
||
xmedia_venc_release_stream(param->venc_chn[i], &venc_stream);
|
||
return XMEDIA_NULL;
|
||
}
|
||
chmod(file_name[i], S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||
ret = sample_comm_venc_save_stream(file_ptr[i], &venc_stream);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("save stream failed!\n");
|
||
free(venc_stream.pack);
|
||
venc_stream.pack = XMEDIA_NULL;
|
||
xmedia_venc_release_stream(param->venc_chn[i], &venc_stream);
|
||
break;
|
||
}
|
||
fclose(file_ptr[i]);
|
||
picture_cnt[i]++;
|
||
}
|
||
|
||
if (((payload_type[i] == PT_H264) || (payload_type[i] == PT_H265)) && (g_user_start == XMEDIA_FALSE)) {
|
||
app_liveserver_send_video_data(i, payload_type[i], &venc_stream);
|
||
}
|
||
|
||
if ((param->save_stream == XMEDIA_TRUE) && (PT_JPEG != payload_type[i])) {
|
||
ret = sample_comm_venc_save_stream(file_ptr[i], &venc_stream);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("save stream failed!\n");
|
||
free(venc_stream.pack);
|
||
venc_stream.pack = XMEDIA_NULL;
|
||
xmedia_venc_release_stream(param->venc_chn[i], &venc_stream);
|
||
break;
|
||
}
|
||
}
|
||
|
||
ret = xmedia_venc_release_stream(param->venc_chn[i], &venc_stream);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("xmedia_venc_release_stream failed!\n");
|
||
free(venc_stream.pack);
|
||
venc_stream.pack = XMEDIA_NULL;
|
||
break;
|
||
}
|
||
|
||
free(venc_stream.pack);
|
||
venc_stream.pack = XMEDIA_NULL;
|
||
}
|
||
}
|
||
|
||
if (param->save_stream == XMEDIA_TRUE) {
|
||
for (i = 0; i < chn_cnt; ++i) {
|
||
if (param->venc_chn[i] < 0) {
|
||
continue;
|
||
}
|
||
if (PT_JPEG != payload_type[i]) {
|
||
fclose(file_ptr[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
return (xmedia_void*)XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_set_jpeg_exif(xmedia_s32 venc_chn)
|
||
{
|
||
xmedia_venc_exif_info exif_info;
|
||
|
||
CHECK_RET(xmedia_venc_get_jpeg_exif_info(venc_chn, &exif_info),"get exif info");
|
||
strncpy((char *)exif_info.image_description, "xmedia test", JPEG_DRSCRIPTION_LENGTH);
|
||
strncpy((char *)exif_info.maker, "xmedia", JPEG_DRSCRIPTION_LENGTH);
|
||
strncpy((char *)exif_info.model, "ipc camera", JPEG_DRSCRIPTION_LENGTH);
|
||
strncpy((char *)exif_info.software, "Exif 2.1.0", JPEG_DRSCRIPTION_LENGTH);
|
||
exif_info.light_source = 1;
|
||
exif_info.focal_length = 6;
|
||
exif_info.focal_length_in35mm_film = 0;
|
||
exif_info.scene_type = 1;
|
||
exif_info.custom_rendered = 1;
|
||
exif_info.scene_capture_type = 1;
|
||
exif_info.gain_control = 0;
|
||
exif_info.contrast = 0;
|
||
exif_info.saturation = 0;
|
||
exif_info.sharpness = 0;
|
||
exif_info.metering_mode = 1;
|
||
CHECK_RET(xmedia_venc_set_jpeg_exif_info(venc_chn, &exif_info),"set exif info");
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_capture_jpeg(xmedia_s32 venc_chn, xmedia_s32 snap_cnt, xmedia_bool save_jpeg, xmedia_bool save_thumbnail, xmedia_char *save_path)
|
||
{
|
||
xmedia_s32 i;
|
||
xmedia_s32 ret;
|
||
xmedia_s32 save_ret = XMEDIA_SUCCESS;
|
||
xmedia_s32 select_ret;
|
||
xmedia_venc_recv_pic_param recv_param;
|
||
xmedia_venc_chn_status st_stat;
|
||
xmedia_venc_stream st_stream;
|
||
struct timeval timeout_val;
|
||
FILE *file_ptr = XMEDIA_NULL;
|
||
static xmedia_u32 recv_cnt[16] = {0};
|
||
xmedia_char jpeg_file[128];
|
||
xmedia_u32 venc_mask = 1 << venc_chn;
|
||
|
||
recv_param.recv_pic_num = snap_cnt;
|
||
ret = xmedia_venc_start_recv_frame(venc_chn, &recv_param);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("xmedia_venc_start_recv_frame faild with%#x!\n", ret);
|
||
return XMEDIA_NULL;
|
||
}
|
||
for (i = 0; i < snap_cnt; i++) {
|
||
timeout_val.tv_sec = 1;
|
||
timeout_val.tv_usec = 0;
|
||
|
||
select_ret = xmedia_venc_select(venc_mask, &timeout_val);
|
||
if (select_ret == XMEDIA_ERRCODE_INVALID_PARAM || select_ret == XMEDIA_FAILURE) {
|
||
SAMPLE_PRT("xmedia_venc_select failed!\n");
|
||
break;
|
||
} else if (select_ret == XMEDIA_ERRCODE_TIMEOUT) {
|
||
continue;
|
||
}
|
||
memset(&st_stream, 0, sizeof(st_stream));
|
||
ret = xmedia_venc_query_status(venc_chn, &st_stat);
|
||
if (ret != XMEDIA_SUCCESS ) {
|
||
SAMPLE_PRT("query stream failed because 0x%x \n", ret);
|
||
continue;
|
||
}
|
||
if(0 == st_stat.cur_packs || 0 == st_stat.left_stream_frames) {
|
||
SAMPLE_PRT("query stream cur_packs:%d or left_stream_frames:%d is 0 \n", \
|
||
st_stat.cur_packs, st_stat.left_stream_frames);
|
||
continue;
|
||
}
|
||
st_stream.pack = (xmedia_venc_pack*)malloc(sizeof(xmedia_venc_pack) * st_stat.cur_packs);
|
||
if (NULL == st_stream.pack) {
|
||
SAMPLE_PRT("malloc memory failed!\n");
|
||
break;
|
||
}
|
||
st_stream.pack_count = st_stat.cur_packs;
|
||
ret = xmedia_venc_get_stream(venc_chn, &st_stream, -1);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("xmedia_venc_get_stream failed with %#x!\n", ret);
|
||
free(st_stream.pack);
|
||
st_stream.pack = NULL;
|
||
break;
|
||
}
|
||
if (save_jpeg) {
|
||
if (file_ptr == NULL) {
|
||
snprintf(jpeg_file, sizeof(jpeg_file), "%s/chn%d_snap_%d.jpg", save_path, venc_chn, recv_cnt[venc_chn]);
|
||
file_ptr = fopen(jpeg_file, "wb");
|
||
if (!file_ptr) {
|
||
SAMPLE_PRT("open file[%s] err!\n", jpeg_file);
|
||
break;
|
||
}
|
||
/*change mod for user*/
|
||
chmod(jpeg_file, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||
}
|
||
save_ret = sample_comm_venc_save_jpeg_stream(venc_chn, file_ptr, &st_stream, recv_cnt[venc_chn], save_path);
|
||
if (save_ret == XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("save jpeg file:%s ok\n", jpeg_file);
|
||
}
|
||
}
|
||
if (save_thumbnail) {
|
||
ret = sample_comm_venc_save_jpeg_thum(save_path, &st_stream, venc_chn, recv_cnt[venc_chn]);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("save thm picture failed!\n");
|
||
break;
|
||
}
|
||
}
|
||
|
||
ret = xmedia_venc_release_stream(venc_chn, &st_stream);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("xmedia_venc_release_stream failed with %#x!\n", ret);
|
||
free(st_stream.pack);
|
||
st_stream.pack = NULL;
|
||
return XMEDIA_NULL;
|
||
}
|
||
free(st_stream.pack);
|
||
st_stream.pack = NULL;
|
||
if (save_ret == XMEDIA_SUCCESS) {
|
||
recv_cnt[venc_chn]++;
|
||
if (file_ptr != NULL) {
|
||
fclose(file_ptr);
|
||
file_ptr = NULL;
|
||
}
|
||
}
|
||
}
|
||
|
||
ret = xmedia_venc_stop_recv_frame(venc_chn);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("xmedia_venc_stop_recv_frame failed with:%#x!\n", ret);
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
|
||
|
||
#define QPMAP_BUF_NUM 8
|
||
#define VENC_QPMAP_MAX_CHN 2
|
||
#define SVP_MAXINUM_LIMIT 10000
|
||
|
||
xmedia_u32 sample_venc_get_qpmap_size(xmedia_u32 width, xmedia_u32 height, xmedia_payload_type type)
|
||
{
|
||
xmedia_u32 stride, align_height;
|
||
xmedia_u32 qpmap_size = 0;
|
||
|
||
if ((width > SVP_MAXINUM_LIMIT) || (height > SVP_MAXINUM_LIMIT)) {
|
||
SAMPLE_PRT("(width:%u || height:%u) > max_limit:%d\n", width, height, SVP_MAXINUM_LIMIT);
|
||
return 0;
|
||
}
|
||
|
||
if (type == PT_H265) {
|
||
stride = DIV_UP(width, 64);
|
||
align_height = DIV_UP(height, 64);
|
||
qpmap_size = stride * align_height * 16;
|
||
} else if (type == PT_H264) {
|
||
stride = DIV_UP(width, 16);
|
||
align_height = DIV_UP(height, 16);
|
||
qpmap_size = stride * align_height;
|
||
}
|
||
|
||
return qpmap_size;
|
||
}
|
||
|
||
xmedia_u32 sample_venc_get_skip_weight_size(xmedia_payload_type type, xmedia_u32 width, xmedia_u32 height)
|
||
{
|
||
xmedia_u32 skip_weight_width;
|
||
xmedia_u32 skip_weight_height;
|
||
xmedia_u32 skip_weight_size = 0;
|
||
if (type == PT_H265) {
|
||
skip_weight_width = DIV_UP(width, 64);
|
||
skip_weight_height = DIV_UP(height, 64);
|
||
skip_weight_size = DIV_UP(skip_weight_width * skip_weight_height, 2);
|
||
} else if (type == PT_H264) {
|
||
skip_weight_width = DIV_UP(width, 16);
|
||
skip_weight_height = DIV_UP(height, 16);
|
||
skip_weight_size = DIV_UP(skip_weight_width * skip_weight_height, 2);
|
||
}
|
||
|
||
return skip_weight_size;
|
||
}
|
||
|
||
xmedia_void* sample_comm_venc_qpmap_sendfrm_proc(xmedia_void* p)
|
||
{
|
||
xmedia_u32 i,j,frm_id;
|
||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||
xmedia_video_frame_info *video_frame;
|
||
xmedia_user_frame_info usr_frame[VENC_QPMAP_MAX_CHN][QPMAP_BUF_NUM];
|
||
sample_venc_qpmap_sendfrm_para *qpmap_para;
|
||
|
||
xmedia_u32 qpmap_size[VENC_QPMAP_MAX_CHN];
|
||
xmedia_u64 qpmap_phy_addr[VENC_QPMAP_MAX_CHN][QPMAP_BUF_NUM];
|
||
xmedia_void* qpmap_vir_addr[VENC_QPMAP_MAX_CHN][QPMAP_BUF_NUM];
|
||
|
||
xmedia_u32 skip_weight_size[VENC_QPMAP_MAX_CHN];
|
||
xmedia_u64 skip_weight_phy_addr[VENC_QPMAP_MAX_CHN][QPMAP_BUF_NUM];
|
||
xmedia_void* skip_weight_vir_addr[VENC_QPMAP_MAX_CHN][QPMAP_BUF_NUM];
|
||
|
||
xmedia_u8 *tmp_vir_addr;
|
||
xmedia_u64 tmp_phy_addr;
|
||
xmedia_u8 *frm_vir_addr_temp;
|
||
|
||
xmedia_vpss_ochn_attr vpss_chn_attr;
|
||
xmedia_venc_chn_attr venc_chn_attr;
|
||
xmedia_payload_type payload_type;
|
||
skip_wight_value skip_value;
|
||
|
||
qpmap_para = (sample_venc_qpmap_sendfrm_para*)p;
|
||
|
||
if (qpmap_para->chn_cnt > VENC_QPMAP_MAX_CHN) {
|
||
SAMPLE_PRT("current func'sample_comm_venc_qpmap_sendfrm_proc' not support venc channal num(%d) > %d\n",qpmap_para->chn_cnt,VENC_QPMAP_MAX_CHN);
|
||
return NULL;
|
||
}
|
||
|
||
for (i = 0; i < qpmap_para->chn_cnt; i++) {
|
||
xmedia_venc_get_chn_attr(qpmap_para->venc_chn[i],&venc_chn_attr);
|
||
|
||
payload_type = venc_chn_attr.venc_attr.en_type;
|
||
|
||
qpmap_size[i] = sample_venc_get_qpmap_size(qpmap_para->size[i].width, qpmap_para->size[i].height, payload_type);
|
||
|
||
skip_weight_size[i] = sample_venc_get_skip_weight_size(venc_chn_attr.venc_attr.en_type,
|
||
qpmap_para->size[i].width, qpmap_para->size[i].height);
|
||
|
||
/*alloc qpmap memory*/
|
||
tmp_phy_addr = xmedia_mmz_alloc( XMEDIA_NULL, "qpmap_buf", qpmap_size[i] * QPMAP_BUF_NUM);
|
||
if (tmp_phy_addr == 0) {
|
||
SAMPLE_PRT("xmedia_mmz_alloc err\n");
|
||
goto error;
|
||
}
|
||
tmp_vir_addr = xmedia_mmz_map(tmp_phy_addr, qpmap_size[i] * QPMAP_BUF_NUM, XMEDIA_FALSE);
|
||
if (tmp_vir_addr == XMEDIA_NULL) {
|
||
SAMPLE_PRT("xmedia_mmz_map err\n");
|
||
goto error;
|
||
}
|
||
for (j = 0; j < QPMAP_BUF_NUM; j++) {
|
||
qpmap_phy_addr[i][j] = tmp_phy_addr + j * qpmap_size[i];
|
||
qpmap_vir_addr[i][j] = tmp_vir_addr + j * qpmap_size[i];
|
||
}
|
||
|
||
/*alloc skipweight memory*/
|
||
tmp_phy_addr = xmedia_mmz_alloc(XMEDIA_NULL, "skip_weight_buf", skip_weight_size[i] * QPMAP_BUF_NUM);
|
||
if (tmp_phy_addr == 0) {
|
||
SAMPLE_PRT("xmedia_mmz_alloc err:0x%x \n",ret);
|
||
goto error;
|
||
}
|
||
tmp_vir_addr = xmedia_mmz_map(tmp_phy_addr, skip_weight_size[i] * QPMAP_BUF_NUM, XMEDIA_FALSE);
|
||
if (tmp_vir_addr == XMEDIA_NULL) {
|
||
SAMPLE_PRT("xmedia_mmz_map err\n");
|
||
goto error;
|
||
}
|
||
for (j = 0; j < QPMAP_BUF_NUM; j++) {
|
||
skip_weight_phy_addr[i][j] = tmp_phy_addr + j * skip_weight_size[i];
|
||
skip_weight_vir_addr[i][j] = tmp_vir_addr + j * skip_weight_size[i];
|
||
}
|
||
}
|
||
|
||
/* set vpss buffer depth*/
|
||
for (i = 0; i < qpmap_para->chn_cnt; i++) {
|
||
ret = xmedia_vpss_get_ochn_attr(qpmap_para->vpss_pipe,qpmap_para->vpss_chn[i],&vpss_chn_attr);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vpss_get_ochn_attr err:0x%x",ret);
|
||
goto error;
|
||
}
|
||
|
||
vpss_chn_attr.depth = 3;
|
||
ret = xmedia_vpss_set_ochn_attr(qpmap_para->vpss_pipe,qpmap_para->vpss_chn[i],&vpss_chn_attr);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vpss_set_ochn_attr err:0x%x",ret);
|
||
goto error;
|
||
}
|
||
}
|
||
|
||
frm_id = 0;
|
||
skip_value.bits.weight1 = 0;
|
||
skip_value.bits.weight2 = 0;
|
||
while (XMEDIA_TRUE == qpmap_para->thread_start) {
|
||
for (i = 0; i < qpmap_para->chn_cnt; i++) {
|
||
video_frame = &usr_frame[i][frm_id].user_frame;
|
||
ret = xmedia_vpss_acquire_ochn_frame(qpmap_para->vpss_pipe, qpmap_para->vpss_chn[i], video_frame, 1000);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("xmedia_vpss_acquire_ochn_frame err:0x%x\n",ret);
|
||
continue;
|
||
}
|
||
|
||
frm_vir_addr_temp = (xmedia_u8 *)qpmap_vir_addr[i][frm_id];
|
||
for (j = 0; j < qpmap_size[i]; j++) {
|
||
*frm_vir_addr_temp = 0x65; //[7]:skip flag; [6]:qp_type flag; [5:0]:qp value ==> set absolute qp = 30
|
||
frm_vir_addr_temp++;
|
||
}
|
||
frm_vir_addr_temp = (xmedia_u8 *)skip_weight_vir_addr[i][frm_id];
|
||
for (j = 0; j < skip_weight_size[i]; j++) {
|
||
*frm_vir_addr_temp = skip_value.u8; // not change inter block skip
|
||
frm_vir_addr_temp++;
|
||
}
|
||
usr_frame[i][frm_id].user_rc_info.skip_weight_valid = 1;
|
||
usr_frame[i][frm_id].user_rc_info.skip_weight_phy_addr = skip_weight_phy_addr[i][frm_id];
|
||
usr_frame[i][frm_id].user_rc_info.qp_map_valid = 1;
|
||
usr_frame[i][frm_id].user_rc_info.qp_map_phy_addr = qpmap_phy_addr[i][frm_id];
|
||
usr_frame[i][frm_id].user_rc_info.blk_start_qp = 30;
|
||
usr_frame[i][frm_id].user_rc_info.frame_type = VENC_FRAME_TYPE_NONE;
|
||
|
||
ret = xmedia_venc_send_frame_ex(qpmap_para->venc_chn[i], &usr_frame[i][frm_id], -1);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_venc_send_frame_ex err:0x%x\n",ret);
|
||
|
||
ret = xmedia_vpss_release_ochn_frame(qpmap_para->vpss_pipe, qpmap_para->vpss_chn[i], video_frame);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vpss_release_ochn_frame err:0x%x", ret);
|
||
goto error;
|
||
}
|
||
break;
|
||
}
|
||
|
||
ret = xmedia_vpss_release_ochn_frame(qpmap_para->vpss_pipe, qpmap_para->vpss_chn[i], video_frame);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vpss_release_ochn_frame err:0x%x", ret);
|
||
goto error;
|
||
}
|
||
|
||
frm_id++;
|
||
if (frm_id >= QPMAP_BUF_NUM) {
|
||
frm_id = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
error:
|
||
for (i = 0; i < qpmap_para->chn_cnt; i++) {
|
||
if (qpmap_phy_addr[i][0] != 0) {
|
||
xmedia_mmz_unmap(qpmap_vir_addr[i][0]);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_mmz_unmap err:0x%x",ret);
|
||
}
|
||
ret = xmedia_mmz_free(qpmap_phy_addr[i][0]);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_mmz_free err:0x%x",ret);
|
||
}
|
||
}
|
||
if (skip_weight_phy_addr[i][0] != 0) {
|
||
xmedia_mmz_unmap(skip_weight_vir_addr[i][0]);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_mmz_unmap err:0x%x",ret);
|
||
}
|
||
ret = xmedia_mmz_free(skip_weight_phy_addr[i][0]);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_mmz_free err:0x%x",ret);
|
||
}
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_qpmap_sendfrm(xmedia_s32 pipe,xmedia_s32 vpss_chn[],xmedia_s32 venc_chn[],xmedia_s32 cnt, xmedia_video_size vpss_size[])
|
||
{
|
||
xmedia_s32 i;
|
||
|
||
g_qpmap_sendfrm_para.thread_start = XMEDIA_TRUE;
|
||
g_qpmap_sendfrm_para.vpss_pipe = pipe;
|
||
g_qpmap_sendfrm_para.chn_cnt = cnt;
|
||
|
||
for(i = 0; i < cnt; i++) {
|
||
g_qpmap_sendfrm_para.venc_chn[i] = venc_chn[i];
|
||
g_qpmap_sendfrm_para.vpss_chn[i] = vpss_chn[i];
|
||
g_qpmap_sendfrm_para.size[i] = vpss_size[i];
|
||
}
|
||
|
||
return pthread_create(&g_venc_qpmap_pid, 0, sample_comm_venc_qpmap_sendfrm_proc, (xmedia_void*)&g_qpmap_sendfrm_para);
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_stop_send_qpmapfrm(xmedia_void)
|
||
{
|
||
g_qpmap_sendfrm_para.thread_start = XMEDIA_FALSE;
|
||
pthread_join(g_venc_qpmap_pid, 0);
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_save_jpeg_block(FILE *fd, xmedia_venc_stream *st_stream, xmedia_u32 cur_row, xmedia_u32 cur_col,
|
||
sample_venc_splicing_para *splicing_para)
|
||
{
|
||
xmedia_s32 i, j;
|
||
static xmedia_u8 rstn = 0xD0;
|
||
xmedia_u32 invalid_data = 0;
|
||
xmedia_u32 mcu_per_ecs;
|
||
xmedia_u32 block_ecs_cnt = 0;
|
||
xmedia_u32 tmp_data_offset = 0;
|
||
xmedia_u32 tmp_data_start = 0;
|
||
xmedia_u32 more_offset = 0;
|
||
xmedia_u32 sos_size = 14;
|
||
xmedia_u8 *tmp_data = XMEDIA_NULL;
|
||
|
||
if (splicing_para->splicing_info.col_cnt == 1) {
|
||
mcu_per_ecs = ALIGN_UP(splicing_para->splicing_info.enc_width, 16) *
|
||
ALIGN_UP(splicing_para->splicing_info.enc_height, 16) / 16 / 16;
|
||
} else {
|
||
mcu_per_ecs = ALIGN_UP(splicing_para->splicing_info.enc_width, 16) / 16;
|
||
}
|
||
|
||
if (cur_row == 0 && cur_col == 0) {
|
||
for (i = st_stream->pack[0].offset;i < st_stream->pack[0].len;i++) {
|
||
if (st_stream->pack[0].vir_addr[i] == 0xFF) {
|
||
i++;
|
||
if (st_stream->pack[0].vir_addr[i] == 0xC0) {
|
||
i += 4;
|
||
st_stream->pack[0].vir_addr[i++] = (xmedia_u8)((splicing_para->splicing_info.dst_height >> 8) & 0xFF);
|
||
st_stream->pack[0].vir_addr[i++] = (xmedia_u8)(splicing_para->splicing_info.dst_height & 0xFF);
|
||
st_stream->pack[0].vir_addr[i++] = (xmedia_u8)((splicing_para->splicing_info.dst_width >> 8) & 0xFF);
|
||
st_stream->pack[0].vir_addr[i++] = (xmedia_u8)(splicing_para->splicing_info.dst_width & 0xFF);
|
||
}
|
||
if (st_stream->pack[0].vir_addr[i] == 0xDD) {
|
||
i += 3;
|
||
st_stream->pack[0].vir_addr[i++] = (xmedia_u8)((mcu_per_ecs >> 8) & 0xFF);
|
||
st_stream->pack[0].vir_addr[i++] = (xmedia_u8)(mcu_per_ecs & 0xFF);
|
||
}
|
||
}
|
||
}
|
||
fwrite(st_stream->pack[0].vir_addr + st_stream->pack[0].offset,
|
||
st_stream->pack[0].len - st_stream->pack[0].offset, 1, fd);
|
||
fflush(fd);
|
||
} else {
|
||
more_offset = sos_size;
|
||
}
|
||
|
||
if (splicing_para->splicing_info.col_cnt == 1) {
|
||
i = st_stream->pack[1].len - 1;
|
||
do {
|
||
if (cur_row == (splicing_para->splicing_info.row_cnt - 1) &&
|
||
cur_col == (splicing_para->splicing_info.col_cnt - 1)) {
|
||
rstn = 0xD0;
|
||
break;
|
||
}
|
||
if (st_stream->pack[1].vir_addr[i] == 0xD9) {
|
||
st_stream->pack[1].vir_addr[i] = rstn;
|
||
rstn++;
|
||
rstn = (rstn == 0XD8) ? 0xD0 : rstn;
|
||
break;
|
||
} else {
|
||
invalid_data++;
|
||
}
|
||
i--;
|
||
} while (i > 0);
|
||
fwrite(st_stream->pack[1].vir_addr + st_stream->pack[1].offset + more_offset,
|
||
st_stream->pack[1].len - st_stream->pack[1].offset - invalid_data - more_offset, 1, fd);
|
||
fflush(fd);
|
||
} else {
|
||
if (cur_col != (splicing_para->splicing_info.col_cnt - 1)) {
|
||
splicing_para->splicing_info.tmp_data[cur_col] = malloc(st_stream->pack[1].len - st_stream->pack[1].offset);
|
||
if (splicing_para->splicing_info.tmp_data[cur_col] == XMEDIA_NULL) {
|
||
SAMPLE_PRT("malloc tmp buf failed!\n");
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
memcpy(splicing_para->splicing_info.tmp_data[cur_col],
|
||
st_stream->pack[1].vir_addr + st_stream->pack[1].offset + more_offset,
|
||
st_stream->pack[1].len - st_stream->pack[1].offset - more_offset);
|
||
splicing_para->splicing_info.tmp_data_len[cur_col] = st_stream->pack[1].len - st_stream->pack[1].offset - more_offset;
|
||
|
||
} else {
|
||
block_ecs_cnt = ALIGN_UP(splicing_para->splicing_info.enc_height, 16) / 16;
|
||
if (cur_col == (splicing_para->splicing_info.col_cnt - 1)) {
|
||
splicing_para->splicing_info.tmp_data[cur_col] = st_stream->pack[1].vir_addr + st_stream->pack[1].offset + more_offset;
|
||
splicing_para->splicing_info.tmp_data_len[cur_col] = st_stream->pack[1].len - st_stream->pack[1].offset - more_offset;
|
||
splicing_para->splicing_info.tmp_data_offset[cur_col] = 0;
|
||
splicing_para->splicing_info.tmp_data_start[cur_col] = 0;
|
||
}
|
||
for (j = 0; j < block_ecs_cnt;j++) {
|
||
for (i = 0;i < splicing_para->splicing_info.col_cnt;i++) {
|
||
tmp_data_offset = splicing_para->splicing_info.tmp_data_offset[i];
|
||
tmp_data_start = splicing_para->splicing_info.tmp_data_start[i];
|
||
tmp_data = splicing_para->splicing_info.tmp_data[i];
|
||
do {
|
||
{
|
||
xmedia_void *start = &tmp_data[tmp_data_offset];
|
||
xmedia_u32 len = splicing_para->splicing_info.tmp_data_len[i];
|
||
xmedia_void *pos = XMEDIA_NULL;
|
||
pos = memchr(start, 0xFF, len - tmp_data_offset);
|
||
if (pos) {
|
||
tmp_data_offset = pos - start + tmp_data_offset;
|
||
}
|
||
}
|
||
if (tmp_data[tmp_data_offset++] == 0xFF &&
|
||
((tmp_data[tmp_data_offset] >= 0xD0 &&
|
||
tmp_data[tmp_data_offset] <= 0xD7) ||
|
||
tmp_data[tmp_data_offset] == 0xD9)) {
|
||
if (j == (block_ecs_cnt - 1) &&
|
||
i == (splicing_para->splicing_info.col_cnt - 1) &&
|
||
cur_row == (splicing_para->splicing_info.row_cnt - 1) &&
|
||
cur_col == (splicing_para->splicing_info.col_cnt - 1)) {
|
||
tmp_data_offset++;
|
||
rstn = 0xD0;
|
||
break;
|
||
}
|
||
tmp_data[tmp_data_offset] = rstn;
|
||
rstn++;
|
||
rstn = (rstn == 0xD8) ? 0xD0 : rstn;
|
||
tmp_data_offset++;
|
||
break;
|
||
}
|
||
} while (tmp_data_offset < splicing_para->splicing_info.tmp_data_len[i]);
|
||
fwrite(splicing_para->splicing_info.tmp_data[i] + tmp_data_start,
|
||
tmp_data_offset - tmp_data_start, 1, fd);
|
||
fflush(fd);
|
||
splicing_para->splicing_info.tmp_data_start[i] = tmp_data_offset;
|
||
splicing_para->splicing_info.tmp_data_offset[i] = tmp_data_offset;
|
||
}
|
||
}
|
||
for (i = 0;i < splicing_para->splicing_info.col_cnt;i++) {
|
||
if (splicing_para->splicing_info.tmp_data[i] != XMEDIA_NULL) {
|
||
if (i < splicing_para->splicing_info.col_cnt - 1) {
|
||
free(splicing_para->splicing_info.tmp_data[i]);
|
||
}
|
||
splicing_para->splicing_info.tmp_data[i] = XMEDIA_NULL;
|
||
splicing_para->splicing_info.tmp_data_offset[i] = 0;
|
||
splicing_para->splicing_info.tmp_data_start[i] = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_deal_jpeg_block(xmedia_u32 cur_row, xmedia_u32 cur_col, sample_venc_splicing_para *splicing_para)
|
||
{
|
||
static xmedia_u32 snap_cnt = 0;
|
||
static FILE *file_ptr = XMEDIA_NULL;
|
||
static xmedia_char jpeg_file[128];
|
||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||
xmedia_s32 save_ret = XMEDIA_SUCCESS;
|
||
xmedia_s32 select_ret;
|
||
xmedia_venc_chn_status st_stat;
|
||
xmedia_venc_stream st_stream;
|
||
struct timeval timeout_val;
|
||
xmedia_s32 venc_chn = splicing_para->venc_chn;
|
||
xmedia_u32 venc_mask = 1 << venc_chn;
|
||
xmedia_bool get_pack = XMEDIA_FALSE;
|
||
|
||
while (get_pack == XMEDIA_FALSE) {
|
||
timeout_val.tv_sec = 2;
|
||
timeout_val.tv_usec = 0;
|
||
|
||
select_ret = xmedia_venc_select(venc_mask, &timeout_val);
|
||
if (select_ret == XMEDIA_ERRCODE_INVALID_PARAM || select_ret == XMEDIA_FAILURE) {
|
||
SAMPLE_PRT("xmedia_venc_select failed!\n");
|
||
if (errno == EINTR) {
|
||
SAMPLE_PRT("interrupted system call,continue\n");
|
||
continue;
|
||
} else {
|
||
break;
|
||
}
|
||
} else if (select_ret == XMEDIA_ERRCODE_TIMEOUT) {
|
||
continue;
|
||
}
|
||
memset(&st_stream, 0, sizeof(st_stream));
|
||
ret = xmedia_venc_query_status(venc_chn, &st_stat);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("query stream failed because 0x%x \n", ret);
|
||
continue;
|
||
}
|
||
if(0 == st_stat.cur_packs || 0 == st_stat.left_stream_frames) {
|
||
SAMPLE_PRT("query stream cur_packs:%d or left_stream_frames:%d is 0 \n", \
|
||
st_stat.cur_packs, st_stat.left_stream_frames);
|
||
continue;
|
||
}
|
||
st_stream.pack = (xmedia_venc_pack*)malloc(sizeof(xmedia_venc_pack) * st_stat.cur_packs);
|
||
if (NULL == st_stream.pack) {
|
||
SAMPLE_PRT("malloc memory failed!\n");
|
||
break;
|
||
}
|
||
st_stream.pack_count = st_stat.cur_packs;
|
||
ret = xmedia_venc_get_stream(venc_chn, &st_stream, -1);
|
||
if (XMEDIA_SUCCESS != ret) {
|
||
SAMPLE_PRT("xmedia_venc_get_stream failed with %#x!\n", ret);
|
||
free(st_stream.pack);
|
||
st_stream.pack = NULL;
|
||
break;
|
||
}
|
||
get_pack = XMEDIA_TRUE;
|
||
if (file_ptr == NULL) {
|
||
snprintf(jpeg_file, sizeof(jpeg_file), "%s/chn%d_snap_%d.jpg", splicing_para->save_path, venc_chn, snap_cnt);
|
||
file_ptr = fopen(jpeg_file, "wb");
|
||
if (!file_ptr) {
|
||
SAMPLE_PRT("open file[%s] err!\n", jpeg_file);
|
||
break;
|
||
}
|
||
/*change mod for user*/
|
||
chmod(jpeg_file, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||
}
|
||
|
||
save_ret = sample_comm_venc_save_jpeg_block(file_ptr, &st_stream, cur_row, cur_col, splicing_para);
|
||
|
||
ret = xmedia_venc_release_stream(venc_chn, &st_stream);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_venc_release_stream failed with %#x!\n", ret);
|
||
free(st_stream.pack);
|
||
st_stream.pack = NULL;
|
||
return XMEDIA_FAILURE;
|
||
}
|
||
free(st_stream.pack);
|
||
st_stream.pack = NULL;
|
||
|
||
if (save_ret != XMEDIA_SUCCESS ||
|
||
(cur_row == (splicing_para->splicing_info.row_cnt - 1) &&
|
||
cur_col == (splicing_para->splicing_info.col_cnt - 1))) {
|
||
fclose(file_ptr);
|
||
file_ptr = NULL;
|
||
snap_cnt++;
|
||
SAMPLE_PRT("save jpeg file:%s ok\n", jpeg_file);
|
||
memset(jpeg_file, 0, sizeof(jpeg_file));
|
||
}
|
||
}
|
||
|
||
return save_ret;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_splicing_proc(sample_venc_splicing_para *splicing_para)
|
||
{
|
||
xmedia_u32 i, j;
|
||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||
|
||
xmedia_vpss_ochn_attr vpss_chn_attr;
|
||
xmedia_venc_recv_pic_param recv_param = {0};
|
||
xmedia_venc_jpeg_param jpeg_param;
|
||
static xmedia_u32 frame_index = 0x2;
|
||
xmedia_s32 handle;
|
||
xmedia_vgs_frame_info task_info = {0};
|
||
xmedia_vgs_block_info block_info = {0};
|
||
xmedia_u32 block_width;
|
||
xmedia_u32 block_height;
|
||
xmedia_u32 block_align_w;
|
||
xmedia_u32 block_remaining;
|
||
|
||
recv_param.recv_pic_num = -1;
|
||
xmedia_venc_start_recv_frame(splicing_para->venc_chn, &recv_param);
|
||
|
||
/* set vpss buffer depth*/
|
||
ret = xmedia_vpss_get_ochn_attr(splicing_para->vpss_pipe, splicing_para->vpss_chn, &vpss_chn_attr);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vpss_get_ochn_attr err:0x%x\n",ret);
|
||
goto error;
|
||
}
|
||
|
||
vpss_chn_attr.depth = 1;
|
||
ret = xmedia_vpss_set_ochn_attr(splicing_para->vpss_pipe, splicing_para->vpss_chn, &vpss_chn_attr);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vpss_set_ochn_attr err:0x%x\n",ret);
|
||
goto error;
|
||
}
|
||
|
||
/* snap one pic and split enc after scale */
|
||
ret = xmedia_vpss_acquire_ochn_frame(splicing_para->vpss_pipe, splicing_para->vpss_chn, &task_info.img_in, 1000);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vpss_acquire_ochn_frame err:0x%x\n",ret);
|
||
goto error;
|
||
}
|
||
if (task_info.img_in.frame.pixel_fmt > XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) {
|
||
SAMPLE_PRT("get pix_fmt: %d but this mode not support\n", task_info.img_in.frame.pixel_fmt);
|
||
goto error;
|
||
}
|
||
|
||
if (splicing_para->splicing_info.col_cnt > 1) {
|
||
xmedia_venc_get_jpeg_param(splicing_para->venc_chn, &jpeg_param);
|
||
jpeg_param.mcu_per_ecs = ALIGN_UP(splicing_para->splicing_info.enc_width, 16) / 16;
|
||
xmedia_venc_set_jpeg_param(splicing_para->venc_chn, &jpeg_param);
|
||
}
|
||
|
||
block_info.dst_img_size.width = splicing_para->splicing_info.dst_width;
|
||
block_info.dst_img_size.height = splicing_para->splicing_info.dst_height;
|
||
|
||
for (i = 0; i < splicing_para->splicing_info.row_cnt; i++) {
|
||
for (j = 0; j < splicing_para->splicing_info.col_cnt; j++) {
|
||
block_info.out_block_offset.x = j * splicing_para->splicing_info.enc_width;
|
||
block_info.out_block_offset.y = i * splicing_para->splicing_info.enc_height;
|
||
|
||
ret = xmedia_vgs_create_job(&handle);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vgs_create_job err:0x%x\n", ret);
|
||
goto error;
|
||
}
|
||
|
||
memcpy(&task_info.img_out, &task_info.img_in, sizeof(xmedia_video_frame_info));
|
||
if ((splicing_para->splicing_info.row_cnt > 1) &&
|
||
(i == (splicing_para->splicing_info.row_cnt - 1))) {
|
||
block_remaining = splicing_para->splicing_info.dst_height % block_info.out_block_offset.y;
|
||
block_height = (block_remaining > 0) ? block_remaining : splicing_para->splicing_info.enc_height;
|
||
} else {
|
||
block_height = splicing_para->splicing_info.enc_height;
|
||
}
|
||
if ((splicing_para->splicing_info.col_cnt > 1) &&
|
||
(j == (splicing_para->splicing_info.col_cnt - 1))) {
|
||
block_remaining = splicing_para->splicing_info.dst_width % block_info.out_block_offset.x;
|
||
block_width = (block_remaining > 0) ? block_remaining : splicing_para->splicing_info.enc_width;
|
||
} else {
|
||
block_width = splicing_para->splicing_info.enc_width;
|
||
}
|
||
block_align_w = ALIGN_UP(splicing_para->splicing_info.enc_width, 16);
|
||
task_info.img_out.frame.width = block_width;
|
||
task_info.img_out.frame.height = block_height;
|
||
|
||
task_info.img_out.frame.stride.y_stride = block_align_w;
|
||
task_info.img_out.frame.stride.c_stride = block_align_w;
|
||
task_info.img_out.frame.addr.y_phy_addr = splicing_para->splicing_info.phy_addr;
|
||
task_info.img_out.frame.addr.c_phy_addr = task_info.img_out.frame.addr.y_phy_addr + \
|
||
(task_info.img_out.frame.stride.y_stride * task_info.img_out.frame.height);
|
||
task_info.img_out.pool_id = splicing_para->splicing_info.pool_id;
|
||
task_info.img_out.mod_id = MOD_ID_USER;
|
||
frame_index += 2;
|
||
task_info.img_out.frame.index = frame_index;
|
||
task_info.img_out.frame.priv_info.isp_info_phy_addr = splicing_para->splicing_info.priv_vb_info.isp_info_phy_addr;
|
||
task_info.img_out.frame.priv_info.isp_info_vir_addr = splicing_para->splicing_info.priv_vb_info.isp_info_vir_addr;
|
||
|
||
ret = xmedia_vgs_add_task_block_scale(handle, &task_info, &block_info, XMEDIA_VIDEO_SCALE_MODE_NORMAL);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vgs_add_task_block_scale err:0x%x\n", ret);
|
||
xmedia_vgs_cancel_job(handle);
|
||
goto error;
|
||
}
|
||
ret = xmedia_vgs_submit_job(handle);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vgs_submit_job err:0x%x\n", ret);
|
||
xmedia_vgs_cancel_job(handle);
|
||
goto error;
|
||
}
|
||
ret = xmedia_vgs_wait_job(handle, 2000);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vgs_wait_job err:0x%x\n", ret);
|
||
xmedia_vgs_cancel_job(handle);
|
||
goto error;
|
||
}
|
||
|
||
/* last scale block may less than enc width x height */
|
||
task_info.img_out.frame.width = splicing_para->splicing_info.enc_width;
|
||
task_info.img_out.frame.height = splicing_para->splicing_info.enc_height;
|
||
|
||
ret = xmedia_venc_send_frame(splicing_para->venc_chn, &task_info.img_out, -1);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_venc_send_frame err:0x%x\n", ret);
|
||
|
||
ret = xmedia_vpss_release_ochn_frame(splicing_para->vpss_pipe, splicing_para->vpss_chn, &task_info.img_in);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vpss_release_ochn_frame err:0x%x\n", ret);
|
||
goto error;
|
||
}
|
||
goto error;
|
||
}
|
||
ret = sample_comm_venc_deal_jpeg_block(i, j, splicing_para);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("sample_comm_venc_deal_jpeg_block err:0x%x\n", ret);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
error:
|
||
ret = xmedia_vpss_release_ochn_frame(splicing_para->vpss_pipe, splicing_para->vpss_chn, &task_info.img_in);
|
||
if (ret != XMEDIA_SUCCESS) {
|
||
SAMPLE_PRT("xmedia_vpss_release_ochn_frame err:0x%x\n", ret);
|
||
}
|
||
|
||
xmedia_venc_stop_recv_frame(splicing_para->venc_chn);
|
||
|
||
return ret;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_start_get_stream(xmedia_s32 venc_chn[], xmedia_s32 cnt, xmedia_bool save_stream, xmedia_bool save_jpeg, xmedia_char *save_path)
|
||
{
|
||
xmedia_u32 i;
|
||
|
||
memset(&g_get_stream_param, 0, sizeof(g_get_stream_param));
|
||
g_get_stream_param.thread_start = XMEDIA_TRUE;
|
||
g_get_stream_param.cnt = cnt;
|
||
for(i = 0; i < cnt; i++) {
|
||
g_get_stream_param.venc_chn[i] = venc_chn[i];
|
||
}
|
||
g_get_stream_param.save_jpeg = save_jpeg;
|
||
g_get_stream_param.save_stream = save_stream;
|
||
|
||
if (save_path != NULL) {
|
||
strcpy(g_get_stream_param.save_path, save_path);
|
||
}
|
||
|
||
return pthread_create(&g_venc_pid, 0, sample_comm_venc_get_stream_proc, (xmedia_void*)&g_get_stream_param);
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_stop_get_stream(void)
|
||
{
|
||
if (XMEDIA_TRUE == g_get_stream_param.thread_start) {
|
||
g_get_stream_param.thread_start = XMEDIA_FALSE;
|
||
|
||
if (g_venc_pid > 0) {
|
||
pthread_join(g_venc_pid, 0);
|
||
}
|
||
}
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_init(xmedia_void)
|
||
{
|
||
xmedia_venc_param_mod mod_param;
|
||
|
||
xmedia_venc_init();
|
||
|
||
/* VPU mini buff mode */
|
||
mod_param.venc_mod_type = MODTYPE_H265E;
|
||
xmedia_venc_get_mod_param(&mod_param);
|
||
mod_param.venc_mod_type = MODTYPE_H265E;
|
||
mod_param.h265e_mod_param.h265e_mini_buf_mode = 1;
|
||
xmedia_venc_set_mod_param(&mod_param);
|
||
|
||
mod_param.venc_mod_type = MODTYPE_H264E;
|
||
xmedia_venc_get_mod_param(&mod_param);
|
||
mod_param.venc_mod_type = MODTYPE_H264E;
|
||
mod_param.h264e_mod_param.h264e_mini_buf_mode = 1;
|
||
xmedia_venc_set_mod_param(&mod_param);
|
||
|
||
mod_param.venc_mod_type = MODTYPE_JPEGE;
|
||
xmedia_venc_get_mod_param(&mod_param);
|
||
mod_param.venc_mod_type = MODTYPE_JPEGE;
|
||
mod_param.jpege_mod_param.jpege_mini_buf_mode = 1;
|
||
xmedia_venc_set_mod_param(&mod_param);
|
||
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
xmedia_s32 sample_comm_venc_exit(xmedia_void)
|
||
{
|
||
if (XMEDIA_TRUE == g_qpmap_sendfrm_para.thread_start) {
|
||
sample_comm_venc_stop_send_qpmapfrm();
|
||
}
|
||
sample_comm_venc_stop_get_stream();
|
||
xmedia_venc_exit();
|
||
return XMEDIA_SUCCESS;
|
||
}
|
||
|
||
|