852 lines
27 KiB
C
852 lines
27 KiB
C
/*
|
|
* Copyright (c) XMEDIA. All rights reserved.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
|
|
#include "sample_comm.h"
|
|
#include "sample_comm_venc.h"
|
|
#include "sample_comm_vpss.h"
|
|
#include "sample_comm_vi.h"
|
|
#include "sample_comm_sys.h"
|
|
#include "sample_comm_isp.h"
|
|
|
|
#include "video_stream.h"
|
|
#include "sample_video.h"
|
|
#include "sample_video_dual.h"
|
|
|
|
#include "venc_log.h"
|
|
#include "frame_cache.h"
|
|
|
|
static int g_start = 0;
|
|
static pthread_t g_recv_pid;
|
|
static sample_venc_getstream_para g_st_param;
|
|
|
|
//common
|
|
struct dual_comm {
|
|
sample_comm_sensor_type sensor_type;
|
|
sample_comm_video_param video_param;
|
|
};
|
|
|
|
// vi config
|
|
struct dual_vi {
|
|
xmedia_s32 vi_dev; /* 0:单板SENSOR0; 2:单板SENSOR2 */
|
|
xmedia_s32 vi_chn;
|
|
xmedia_s32 vi_pipe;
|
|
sample_vi_config vi_cfg;
|
|
};
|
|
|
|
// isp config
|
|
struct dual_isp {
|
|
sample_isp_param isp_param;
|
|
};
|
|
|
|
// vpss config
|
|
struct dual_vpss {
|
|
xmedia_s32 vpss_pipe;
|
|
xmedia_s32 vpss_ichn;
|
|
xmedia_s32 vpss_ochn;
|
|
sample_vpss_config vpss_cfg;
|
|
};
|
|
|
|
// venc config
|
|
struct dual_venc {
|
|
xmedia_s32 venc_chn;
|
|
sample_venc_config venc_cfg;
|
|
};
|
|
|
|
struct dual_stream {
|
|
xmedia_s32 stream_id;
|
|
|
|
struct dual_comm comm;
|
|
struct dual_vi vi;
|
|
struct dual_isp isp;
|
|
struct dual_vpss vpss;
|
|
struct dual_venc venc;
|
|
};
|
|
|
|
#define STREAM_NUMS 4
|
|
|
|
static struct dual_stream g_stream[STREAM_NUMS];
|
|
|
|
static void sample_dual_config_comm(struct dual_comm* comm, sample_comm_sensor_type sns_type)
|
|
{
|
|
comm->sensor_type = sns_type;
|
|
comm->video_param.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
|
|
comm->video_param.pixel_fmt = XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420;
|
|
comm->video_param.data_width = XMEDIA_VIDEO_DATA_WIDTH_8;
|
|
comm->video_param.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
|
|
}
|
|
|
|
static void sample_dual_config_vi(struct dual_vi* vi,
|
|
xmedia_s32 vi_chn,
|
|
xmedia_s32 vi_dev,
|
|
xmedia_s32 vi_pipe,
|
|
sample_comm_sensor_type sns_type)
|
|
{
|
|
vi->vi_chn = vi_chn;
|
|
vi->vi_dev = vi_dev;
|
|
vi->vi_pipe = vi_pipe;
|
|
vi->vi_cfg.dev_info[vi_dev].dev_no = vi_dev;
|
|
vi->vi_cfg.dev_info[vi_dev].dev_en = XMEDIA_TRUE;
|
|
vi->vi_cfg.dev_info[vi_dev].sensor_type = sns_type;
|
|
vi->vi_cfg.pipe_info[vi_pipe].pipe_no = vi_pipe;
|
|
vi->vi_cfg.pipe_info[vi_pipe].pipe_en = XMEDIA_TRUE;
|
|
vi->vi_cfg.pipe_info[vi_pipe].chn_info[vi_chn].chn_no = vi_chn;
|
|
vi->vi_cfg.pipe_info[vi_pipe].chn_info[vi_chn].chn_en = XMEDIA_TRUE;
|
|
vi->vi_cfg.dev_bind_pipe[vi_dev].pipe[0] = vi_pipe;
|
|
vi->vi_cfg.dev_bind_pipe[vi_dev].pipe[1] = -1;
|
|
}
|
|
|
|
static void sample_dual_config_isp(struct dual_isp* isp,
|
|
xmedia_s32 vi_pipe,
|
|
sample_comm_sensor_type sns_type)
|
|
{
|
|
xmedia_u32 framerate = 0;
|
|
vi_sensor_info sensor_info = {0};
|
|
|
|
sample_comm_vi_get_sensor_info(sns_type, &sensor_info);
|
|
sample_comm_vi_get_framerate_by_sensor(sns_type, &framerate);
|
|
|
|
// isp config init
|
|
isp->isp_param.isp_info[vi_pipe].isp_config.fps = framerate;
|
|
isp->isp_param.isp_info[vi_pipe].isp_config.mode_config.work_mode = XMEDIA_ISP_WORK_MODE_MASTER;
|
|
isp->isp_param.isp_info[vi_pipe].isp_config.mode_config.master_mode.blend_stat_enable = XMEDIA_FALSE;
|
|
isp->isp_param.isp_info[vi_pipe].isp_config.mode_config.master_mode.slave_num = 0;
|
|
isp->isp_param.isp_info[vi_pipe].isp_config.pixel_fmt = sensor_info.pixel_format;
|
|
isp->isp_param.isp_info[vi_pipe].isp_config.size.height = sensor_info.height;
|
|
isp->isp_param.isp_info[vi_pipe].isp_config.size.width = sensor_info.width;
|
|
isp->isp_param.isp_info[vi_pipe].isp_config.wdr_mode = sensor_info.wdr_mode;
|
|
|
|
// isp pipe init
|
|
isp->isp_param.pipe[vi_pipe] = vi_pipe;
|
|
isp->isp_param.isp_info[vi_pipe].flip = XMEDIA_FALSE;
|
|
isp->isp_param.isp_info[vi_pipe].mirror = XMEDIA_FALSE;
|
|
isp->isp_param.isp_info[vi_pipe].isp_pipe_en = XMEDIA_TRUE;
|
|
isp->isp_param.isp_info[vi_pipe].isp_sensor_en = XMEDIA_TRUE;
|
|
isp->isp_param.isp_info[vi_pipe].sensor_type = sns_type;
|
|
}
|
|
|
|
static void sample_dual_config_vpss(struct dual_vpss* vpss,
|
|
xmedia_s32 vpss_pipe,
|
|
xmedia_s32 vpss_ichn,
|
|
xmedia_s32 vpss_ochn)
|
|
{
|
|
vpss->vpss_pipe = vpss_pipe;
|
|
vpss->vpss_ichn = vpss_ichn;
|
|
vpss->vpss_ochn = vpss_ochn;
|
|
//vpss->vpss_cfg = ;
|
|
}
|
|
|
|
static void sample_dual_config_venc(struct dual_venc* venc,
|
|
xmedia_s32 venc_chnl)
|
|
{
|
|
venc->venc_chn = venc_chnl;
|
|
venc->venc_cfg.chn_info[venc_chnl].venc_en = XMEDIA_TRUE;
|
|
venc->venc_cfg.chn_info[venc_chnl].venc_chn = venc_chnl;
|
|
venc->venc_cfg.chn_info[venc_chnl].payload_type = PT_H264;
|
|
venc->venc_cfg.chn_info[venc_chnl].rc_mode = VENC_RC_MODE_H264CBR;
|
|
}
|
|
|
|
static void sammple_dual_stream_config(void)
|
|
{
|
|
xmedia_s32 id;
|
|
xmedia_s32 vi_dev[STREAM_NUMS] = {0, 0, 2, 2};
|
|
xmedia_s32 vi_pipe[STREAM_NUMS] = {0, 0, 1, 1};
|
|
xmedia_s32 vi_chn[STREAM_NUMS] = {0, 0, 0, 0};
|
|
xmedia_s32 vpss_pipe[STREAM_NUMS] = {0, 0, 1, 1};
|
|
xmedia_s32 vpss_ichn[STREAM_NUMS] = {0, 0, 0, 0};
|
|
xmedia_s32 vpss_ochn[STREAM_NUMS] = {0, 1, 0, 1};
|
|
xmedia_s32 venc_chnl[STREAM_NUMS] = {0, 1, 2, 3};
|
|
sample_comm_sensor_type sns_type[STREAM_NUMS] = {SENSOR0_TYPE, SENSOR0_TYPE, SENSOR1_TYPE, SENSOR1_TYPE};
|
|
|
|
for (id = 0; id < STREAM_NUMS; id++) {
|
|
g_stream[id].stream_id = id;
|
|
|
|
sample_dual_config_comm(&g_stream[id].comm, sns_type[id]);
|
|
sample_dual_config_vi(&g_stream[id].vi, vi_chn[id], vi_dev[id], vi_pipe[id], sns_type[id]);
|
|
sample_dual_config_isp(&g_stream[id].isp, vi_pipe[id], sns_type[id]);
|
|
sample_dual_config_vpss(&g_stream[id].vpss, vpss_pipe[id], vpss_ichn[id], vpss_ochn[id]);
|
|
sample_dual_config_venc(&g_stream[id].venc, venc_chnl[id]);
|
|
}
|
|
}
|
|
|
|
static int sample_dual_sys_init(void)
|
|
{
|
|
xmedia_s32 ret;
|
|
xmedia_s32 id;
|
|
xmedia_s32 blk_size, pool_id;
|
|
xmedia_s32 vi_pipe;
|
|
sample_comm_sensor_type sensor_type;
|
|
vi_sensor_info sensor_info = {0};
|
|
xmedia_video_size pic_size = {0};
|
|
sample_sys_config sys_config = {0};
|
|
sample_comm_video_param* video_param = NULL;
|
|
|
|
func_entry();
|
|
|
|
sammple_dual_stream_config();
|
|
|
|
pool_id = 0;
|
|
|
|
for (id = 0; id < STREAM_NUMS; id++) {
|
|
sensor_type = g_stream[id].comm.sensor_type;
|
|
|
|
sample_comm_vi_get_sensor_info(sensor_type, &sensor_info);
|
|
|
|
// sys init
|
|
vi_pipe = g_stream[id].vi.vi_pipe;
|
|
sys_config.sys_conf.pipe_mode[vi_pipe].vicap_viproc_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
sys_config.sys_conf.pipe_mode[vi_pipe].viproc_vpss_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
sys_config.sys_conf.pipe_mode[vi_pipe].gdc_vpss_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
|
|
pic_size.width = sensor_info.width;
|
|
pic_size.height = sensor_info.height;
|
|
|
|
venc_logd("resolution: w(%d) x h(%d).\n", pic_size.width, pic_size.height);
|
|
|
|
video_param = &g_stream[id].comm.video_param;
|
|
blk_size = sample_comm_sys_get_buffer_size(pic_size,
|
|
video_param->video_fmt,
|
|
sensor_info.pixel_format,
|
|
sensor_info.bit_width,
|
|
video_param->compress_mode);
|
|
sys_config.vb_conf.common_pool[pool_id].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[pool_id].block_cnt = 5;
|
|
venc_logd("allocate cache pool %d: size(%d) x cnt(%d)\n", pool_id, blk_size, 5);
|
|
pool_id++;
|
|
|
|
blk_size = sample_comm_sys_get_buffer_size(pic_size,
|
|
video_param->video_fmt,
|
|
video_param->pixel_fmt,
|
|
video_param->data_width,
|
|
video_param->compress_mode);
|
|
sys_config.vb_conf.common_pool[pool_id].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[pool_id].block_cnt = 5;
|
|
venc_logd("allocate cache pool %d: size(%d) x cnt(%d)\n", pool_id, blk_size, 5);
|
|
pool_id++;
|
|
}
|
|
|
|
sys_config.vb_conf.supplement_config = (1 << 0);
|
|
sys_config.vb_conf.supplement_config |= (1 << 1);
|
|
|
|
ret = sample_comm_sys_init(&sys_config);
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
venc_loge("sample_comm_sys_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
//in online-online mode,vi and vpss must be reset at the same time
|
|
ret = sample_comm_vi_init();
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
venc_loge("sample_comm_vi_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = sample_comm_vpss_init();
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
venc_loge("sample_comm_vpss_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = sample_comm_venc_init();
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
venc_loge("sample_comm_venc_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
func_success();
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static int sample_dual_sys_deinit(void)
|
|
{
|
|
sample_comm_venc_exit();
|
|
|
|
sample_comm_vpss_exit();
|
|
|
|
sample_comm_vi_exit();
|
|
|
|
sample_comm_sys_exit();
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static FILE* fp[4] = {NULL, NULL, NULL, NULL};
|
|
char filename[4][32] = {
|
|
{"stream_dev.h264"},
|
|
{"stream_1.h264"},
|
|
{"stream_2.h264"},
|
|
{"stream_3.h264"}
|
|
};
|
|
|
|
struct dual_head {
|
|
unsigned int id;
|
|
unsigned int stream_offset;
|
|
unsigned int stream_size;
|
|
unsigned char reserve[4];
|
|
};
|
|
|
|
void save_stream(char* stream, int length)
|
|
{
|
|
int w_actl = 0;
|
|
int recv_size = length;
|
|
unsigned int offset, size;
|
|
unsigned int id = 0;
|
|
unsigned char* tmp = (unsigned char*)stream;
|
|
struct dual_head* stream_head = NULL;
|
|
|
|
while (recv_size > 0) {
|
|
stream_head = (struct dual_head*)stream;
|
|
id = stream_head->id;
|
|
offset = stream_head->stream_offset;
|
|
size = stream_head->stream_size;
|
|
|
|
if (id >= STREAM_NUMS) {
|
|
printf("Error: Invalid stream id.\n");
|
|
return ;
|
|
}
|
|
|
|
//printf("id(%u), off(%u), size(%u)\n", id, offset, size);
|
|
tmp += offset;
|
|
if (fp[id] != NULL) {
|
|
w_actl = fwrite(tmp, 1, size, fp[id]);
|
|
}
|
|
|
|
if (w_actl != size) {
|
|
//printf("Warning: exp(%d) != acl(%d).", size, w_actl);
|
|
}
|
|
|
|
tmp += size;
|
|
|
|
recv_size -= (offset + size);
|
|
}
|
|
}
|
|
|
|
static int sample_dual_save_data(xmedia_venc_stream* pst_stream, int id)
|
|
{
|
|
int i = 0;
|
|
xmedia_venc_pack *pst_data = NULL;
|
|
unsigned char *s = NULL;
|
|
unsigned int data_len = 0;
|
|
unsigned int copy_size = 0;
|
|
struct dual_head head = {0};
|
|
|
|
uvc_cache_t *uvc_cache = uvc_cache_get();
|
|
frame_node_t *fnode = NULL;
|
|
|
|
if (uvc_cache) {
|
|
get_node_from_queue(uvc_cache->free_queue, &fnode);
|
|
}
|
|
|
|
if (!fnode) {
|
|
venc_logd("drop frame.\n");
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
fnode->used = sizeof(struct dual_head);
|
|
|
|
head.id = id;
|
|
head.stream_offset = sizeof(struct dual_head);
|
|
head.stream_size = 0;
|
|
|
|
for (i = 0; i < pst_stream->pack_count; ++i) {
|
|
pst_data = &pst_stream->pack[i];
|
|
s = pst_data->vir_addr + pst_data->offset;
|
|
data_len = pst_data->len - pst_data->offset;
|
|
copy_size = data_len < (fnode->length - fnode->used) ? data_len : (fnode->length - fnode->used);
|
|
|
|
if (copy_size > 0) {
|
|
memcpy(fnode->mem + fnode->used, s, copy_size);
|
|
fnode->used += copy_size;
|
|
head.stream_size += copy_size;
|
|
}
|
|
|
|
if (data_len > copy_size) {
|
|
venc_logw("fnode->length = %u\n", fnode->length);
|
|
venc_logw("WARN: missing pack. exp(%u) != act(%u)\n", data_len, copy_size);
|
|
}
|
|
}
|
|
|
|
memcpy(fnode->mem, (void*)&head, sizeof(struct dual_head));
|
|
|
|
//fwrite((char*)(fnode->mem), 1, 16, fp[0]);
|
|
if (fp[id] != NULL) {
|
|
//fwrite((char*)(fnode->mem + head.stream_offset), 1, head.stream_size, fp[id]);
|
|
//save_stream((char*)fnode->mem, fnode->used);
|
|
}
|
|
|
|
venc_logd("send size(%u)\n", fnode->used);
|
|
put_node_to_queue(uvc_cache->ok_queue, fnode);
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static int sample_dual_save_stream(xmedia_payload_type en_type, xmedia_venc_stream *pst_stream, int id)
|
|
{
|
|
xmedia_s32 ret = XMEDIA_FAILURE;
|
|
|
|
if (PT_H264 == en_type) {
|
|
ret = sample_dual_save_data(pst_stream, id);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void* sample_dual_stream_proc(void* arg)
|
|
{
|
|
xmedia_s32 i;
|
|
xmedia_s32 ret = XMEDIA_FAILURE;
|
|
|
|
xmedia_venc_chn_attr venc_chn_attr;
|
|
xmedia_payload_type payload_type[VENC_MAX_CHN_NUM];
|
|
sample_venc_getstream_para *param = (sample_venc_getstream_para*)arg;
|
|
xmedia_s32 chn_cnt = param->cnt;
|
|
|
|
struct timeval time_out;
|
|
xmedia_venc_stream venc_stream;
|
|
xmedia_venc_chn_status stat;
|
|
xmedia_u32 venc_mask = 0;
|
|
|
|
if (chn_cnt >= VENC_MAX_CHN_NUM) {
|
|
venc_loge("input venc chn count invaild\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
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) {
|
|
venc_loge("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;
|
|
venc_mask |= 1 << param->venc_chn[i];
|
|
if (fp[i] == NULL) {
|
|
fp[i] = fopen((char*)filename[i], "w+");
|
|
}
|
|
}
|
|
|
|
venc_logi("Dual start.\n");
|
|
while (param->thread_start) {
|
|
time_out.tv_sec = 2;
|
|
time_out.tv_usec = 0;
|
|
ret = xmedia_venc_select(venc_mask, &time_out);
|
|
if (ret == XMEDIA_ERRCODE_INVALID_PARAM || ret == XMEDIA_FAILURE) {
|
|
venc_loge("select err\n");
|
|
break;
|
|
} else if (ret == XMEDIA_ERRCODE_TIMEOUT) {
|
|
param->stream_timeout_cnt++;
|
|
venc_logd("get venc stream time out, continue. \n");
|
|
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) {
|
|
venc_logd("xmedia_venc_query_status chn[%d] failed with %#x!\n", i, ret);
|
|
break;
|
|
}
|
|
|
|
if (0 == stat.cur_packs) {
|
|
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) {
|
|
venc_logd("malloc stream pack failed!\n");
|
|
break;
|
|
}
|
|
|
|
venc_stream.pack_count = stat.cur_packs;
|
|
ret = xmedia_venc_get_stream(param->venc_chn[i], &venc_stream, XMEDIA_TRUE);
|
|
if (XMEDIA_SUCCESS != ret) {
|
|
free(venc_stream.pack);
|
|
venc_stream.pack = XMEDIA_NULL;
|
|
xmedia_venc_release_stream(param->venc_chn[i], &venc_stream);
|
|
venc_loge("xmedia_venc_get_stream failed with %#x!\n", ret);
|
|
break;
|
|
}
|
|
|
|
sample_dual_save_stream(payload_type[i], &venc_stream, i);
|
|
|
|
ret = xmedia_venc_release_stream(param->venc_chn[i], &venc_stream);
|
|
if (XMEDIA_SUCCESS != ret) {
|
|
venc_loge("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;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if (fp[i] != NULL) {
|
|
fclose(fp[i]);
|
|
}
|
|
|
|
fp[i] = NULL;
|
|
}
|
|
|
|
venc_logi("Dual stream exit.\n");
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static int sample_dual_start_get_stream()
|
|
{
|
|
int i, rc;
|
|
|
|
g_st_param.cnt = STREAM_NUMS;
|
|
g_st_param.thread_start = XMEDIA_TRUE;
|
|
|
|
for (i = 0; i < STREAM_NUMS; i++) {
|
|
g_st_param.venc_chn[i] = g_stream[i].venc.venc_chn;
|
|
}
|
|
|
|
rc = pthread_create(&g_recv_pid, NULL, sample_dual_stream_proc, (void*)&g_st_param);
|
|
if (rc < 0) {
|
|
venc_loge("Create sample_dual_stream_proc failed.\n");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int sample_dual_stop_get_stream(void)
|
|
{
|
|
if (XMEDIA_TRUE == g_st_param.thread_start) {
|
|
g_st_param.thread_start = XMEDIA_FALSE;
|
|
pthread_join(g_recv_pid, 0);
|
|
}
|
|
|
|
venc_logi("stop get Dual stream ok.\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int sample_dual_normalp_classic(void)
|
|
{
|
|
xmedia_s32 id;
|
|
xmedia_s32 ret = XMEDIA_SUCCESS;
|
|
xmedia_u32 framerate = 0;
|
|
xmedia_video_size pic_size = {0};
|
|
xmedia_video_size vpss_ochn_size = {0};
|
|
//xmedia_isp_config isp_config = {0};
|
|
xmedia_payload_type en_payload = PT_H264;
|
|
vi_sensor_info sensor_info = {0};
|
|
|
|
xmedia_s32 venc_chn_0, venc_chn_1;
|
|
xmedia_s32 vi_pipe, vi_chn;
|
|
xmedia_s32 vpss_pipe, vpss_ichn, vpss_ochn_0, vpss_ochn_1;
|
|
sample_comm_sensor_type sensor_type;
|
|
sample_isp_param* isp_param = NULL;
|
|
sample_vi_config* vi_config = NULL;
|
|
sample_vpss_config* vpss_config = NULL;
|
|
sample_venc_config* venc_config = NULL;
|
|
sample_comm_video_param* video_param = NULL;
|
|
|
|
for (id = 0; id < STREAM_NUMS; id++) {
|
|
#if 0
|
|
g_vi_config.dev_info[g_vi_dev].dev_en = XMEDIA_TRUE;
|
|
g_vi_config.dev_info[g_vi_dev].dev_no = g_vi_dev;
|
|
g_vi_config.dev_info[g_vi_dev].sensor_type = g_sensor_type;
|
|
g_vi_config.pipe_info[g_vi_pipe].pipe_en = XMEDIA_TRUE;
|
|
g_vi_config.pipe_info[g_vi_pipe].pipe_no = g_vi_pipe;
|
|
g_vi_config.pipe_info[g_vi_pipe].chn_info[g_vi_chn].chn_en = XMEDIA_TRUE;
|
|
g_vi_config.pipe_info[g_vi_pipe].chn_info[g_vi_chn].chn_no = g_vi_chn;
|
|
g_vi_config.dev_bind_pipe[g_vi_dev].pipe[0] = g_vi_pipe;
|
|
g_vi_config.dev_bind_pipe[g_vi_dev].pipe[1] = -1;
|
|
#endif
|
|
sensor_type = g_stream[id].comm.sensor_type;
|
|
|
|
sample_comm_vi_get_sensor_info(sensor_type, &sensor_info);
|
|
sample_comm_vi_get_framerate_by_sensor(sensor_type, &framerate);
|
|
|
|
pic_size.height = sensor_info.height;
|
|
pic_size.width = sensor_info.width;
|
|
|
|
#if 0
|
|
isp_config.fps = framerate;
|
|
isp_config.mode_config.work_mode = XMEDIA_ISP_WORK_MODE_MASTER;
|
|
isp_config.mode_config.master_mode.blend_stat_enable = XMEDIA_FALSE;
|
|
isp_config.mode_config.master_mode.slave_num = 0;
|
|
isp_config.pixel_fmt = sensor_info.pixel_format;
|
|
isp_config.size.height = sensor_info.height;
|
|
isp_config.size.width = sensor_info.width;
|
|
isp_config.wdr_mode = sensor_info.wdr_mode;
|
|
|
|
// isp pipe init
|
|
g_isp_param.pipe[g_vi_pipe] = g_vi_pipe;
|
|
g_isp_param.isp_info[g_vi_pipe].sensor_type = g_sensor_type;
|
|
g_isp_param.isp_info[g_vi_pipe].flip = XMEDIA_FALSE;
|
|
g_isp_param.isp_info[g_vi_pipe].mirror = XMEDIA_FALSE;
|
|
g_isp_param.isp_info[g_vi_pipe].isp_pipe_en = XMEDIA_TRUE;
|
|
g_isp_param.isp_info[g_vi_pipe].isp_sensor_en = XMEDIA_TRUE;
|
|
|
|
memcpy(&(g_isp_param.isp_info[g_vi_pipe].isp_config), &isp_config, sizeof(xmedia_isp_config));
|
|
#endif
|
|
|
|
// isp init
|
|
isp_param = &g_stream[id].isp.isp_param;
|
|
vi_config = &g_stream[id].vi.vi_cfg;
|
|
|
|
ret = sample_comm_isp_init(isp_param, vi_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] isp init failed!\n", id);
|
|
}
|
|
|
|
// vi start
|
|
vi_config = &g_stream[id].vi.vi_cfg;
|
|
video_param = &g_stream[id].comm.video_param;
|
|
|
|
ret = sample_comm_vi_start(vi_config, video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] start vi failed!\n", id);
|
|
}
|
|
|
|
// isp start
|
|
isp_param = &g_stream[id].isp.isp_param;
|
|
|
|
ret = sample_comm_isp_start(isp_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] start isp failed!\n", id);
|
|
}
|
|
|
|
// vpss config
|
|
vpss_pipe = g_stream[id].vpss.vpss_pipe;
|
|
vpss_ichn = g_stream[id].vpss.vpss_ichn;
|
|
vpss_ochn_0 = g_stream[id].vpss.vpss_ochn;
|
|
vpss_ochn_1 = g_stream[id + 1].vpss.vpss_ochn;
|
|
vpss_config = &g_stream[id].vpss.vpss_cfg;
|
|
video_param = &g_stream[id].comm.video_param;
|
|
|
|
ret = sample_comm_vpss_get_default_pipe_cfg(&vpss_config->pipe_info[vpss_pipe].pipe_config,
|
|
pic_size,
|
|
video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] get default pipe cfg failed !\n", id);
|
|
}
|
|
|
|
get_user_format(&en_payload, &pic_size, NULL);
|
|
vpss_ochn_size.width = pic_size.width;
|
|
vpss_ochn_size.height = pic_size.height;
|
|
|
|
vpss_config->pipe_info[vpss_pipe].pipe_en = XMEDIA_TRUE;
|
|
vpss_config->pipe_info[vpss_pipe].pipe_no = vpss_pipe;
|
|
#if 0
|
|
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn].chn_no = vpss_ochn;
|
|
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn].chn_en = XMEDIA_TRUE;
|
|
#else
|
|
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_0].chn_no = vpss_ochn_0;
|
|
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_0].chn_en = XMEDIA_TRUE;
|
|
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_1].chn_no = vpss_ochn_1;
|
|
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_1].chn_en = XMEDIA_TRUE;
|
|
#endif
|
|
#if 0
|
|
ret = sample_comm_vpss_get_default_ochn_cfg(
|
|
&vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn].chn_config,
|
|
vpss_ochn_size,
|
|
video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] get default pipe cfg failed !\n", id);
|
|
}
|
|
#else
|
|
ret = sample_comm_vpss_get_default_ochn_cfg(
|
|
&vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_0].chn_config,
|
|
vpss_ochn_size,
|
|
video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] get default pipe cfg failed !\n", id);
|
|
}
|
|
|
|
ret = sample_comm_vpss_get_default_ochn_cfg(
|
|
&vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_1].chn_config,
|
|
vpss_ochn_size,
|
|
video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] get default pipe cfg failed !\n", id + 1);
|
|
}
|
|
#endif
|
|
// vpss start
|
|
ret = sample_comm_vpss_start(vpss_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] vpss start failed !\n", id);
|
|
}
|
|
|
|
vi_chn = g_stream[id].vi.vi_chn;
|
|
vi_pipe = g_stream[id].vi.vi_pipe;
|
|
vpss_ichn = g_stream[id].vpss.vpss_ichn;
|
|
vpss_pipe = g_stream[id].vpss.vpss_pipe;
|
|
ret = sample_comm_sys_vi_bind_vpss(vi_pipe, vi_chn, vpss_pipe, vpss_ichn);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] vi bind vpss failed !\n", id);
|
|
}
|
|
|
|
//venc init
|
|
venc_chn_0 = g_stream[id].venc.venc_chn;
|
|
venc_config = &g_stream[id].venc.venc_cfg;
|
|
|
|
venc_config->chn_info[venc_chn_0].venc_chn = venc_chn_0;
|
|
venc_config->chn_info[venc_chn_0].venc_en = XMEDIA_TRUE;
|
|
venc_config->chn_info[venc_chn_0].payload_type = en_payload;
|
|
venc_config->chn_info[venc_chn_0].rc_mode = VENC_RC_MODE_H264CBR;
|
|
|
|
sample_comm_venc_get_default_chn_info(vpss_ochn_size,
|
|
framerate,
|
|
&venc_config->chn_info[venc_chn_0]);
|
|
|
|
ret = sample_comm_venc_start(venc_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] venc start failed !\n", id);
|
|
}
|
|
|
|
venc_chn_1 = g_stream[id + 1].venc.venc_chn;
|
|
venc_config = &g_stream[id + 1].venc.venc_cfg;
|
|
|
|
venc_config->chn_info[venc_chn_1].venc_chn = venc_chn_1;
|
|
venc_config->chn_info[venc_chn_1].venc_en = XMEDIA_TRUE;
|
|
venc_config->chn_info[venc_chn_1].payload_type = en_payload;
|
|
venc_config->chn_info[venc_chn_1].rc_mode = VENC_RC_MODE_H264CBR;
|
|
|
|
sample_comm_venc_get_default_chn_info(vpss_ochn_size,
|
|
framerate,
|
|
&venc_config->chn_info[venc_chn_1]);
|
|
|
|
ret = sample_comm_venc_start(venc_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] venc start failed !\n", id);
|
|
}
|
|
|
|
ret = sample_comm_sys_vpss_bind_venc(vpss_pipe, vpss_ochn_0, venc_chn_0);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] vpss bind venc failed !\n", id);
|
|
}
|
|
|
|
ret = sample_comm_sys_vpss_bind_venc(vpss_pipe, vpss_ochn_1, venc_chn_1);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
venc_loge("stream[%d] vpss bind venc failed !\n", id);
|
|
}
|
|
|
|
id++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************
|
|
* Processing Unit Operation Functions
|
|
*******************************************************/
|
|
|
|
/* Processing Unit Operation Functions End */
|
|
|
|
/*******************************************************
|
|
* Input Terminal Operation Functions
|
|
*******************************************************/
|
|
|
|
/* Input Terminal Operation Functions End */
|
|
|
|
/*******************************************************
|
|
* Stream Control Operation Functions
|
|
*******************************************************/
|
|
int sample_dual_set_idr(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int sample_dual_init(void)
|
|
{
|
|
sample_dual_sys_init();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sample_dual_startup(void)
|
|
{
|
|
venc_logi("Dual stream startup.\n");
|
|
g_start = 1;
|
|
|
|
if (sample_dual_normalp_classic() < 0) {
|
|
return -1;
|
|
}
|
|
|
|
sample_dual_start_get_stream();
|
|
venc_logi("Dual stream startup ok.\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sample_dual_shutdown(void)
|
|
{
|
|
xmedia_s32 id;
|
|
xmedia_s32 vi_pipe, vi_chn;
|
|
xmedia_s32 vpss_pipe, vpss_ichn, vpss_ochn_0, vpss_ochn_1;
|
|
xmedia_s32 venc_chn_0, venc_chn_1;
|
|
sample_venc_config* venc_config = NULL;
|
|
sample_vpss_config* vpss_config = NULL;
|
|
sample_isp_param* isp_param = NULL;
|
|
sample_vi_config* vi_config = NULL;
|
|
|
|
if (!g_start) {
|
|
return 0;
|
|
}
|
|
|
|
sample_dual_stop_get_stream();
|
|
|
|
for (id = 0; id < STREAM_NUMS; id++) {
|
|
venc_config = &g_stream[id].venc.venc_cfg;
|
|
sample_comm_venc_stop(venc_config);
|
|
|
|
venc_config = &g_stream[id + 1].venc.venc_cfg;
|
|
sample_comm_venc_stop(venc_config);
|
|
|
|
vpss_pipe = g_stream[id].vpss.vpss_pipe;
|
|
vpss_ichn = g_stream[id].vpss.vpss_ichn;
|
|
vpss_ochn_0 = g_stream[id].vpss.vpss_ochn;
|
|
vpss_ochn_1 = g_stream[id + 1].vpss.vpss_ochn;
|
|
venc_chn_0 = g_stream[id].venc.venc_chn;
|
|
venc_chn_1 = g_stream[id + 1].venc.venc_chn;
|
|
|
|
sample_comm_sys_vpss_unbind_venc(vpss_pipe, vpss_ochn_0, venc_chn_0);
|
|
sample_comm_sys_vpss_unbind_venc(vpss_pipe, vpss_ochn_1, venc_chn_1);
|
|
|
|
vi_pipe = g_stream[id].vi.vi_pipe;
|
|
vi_chn = g_stream[id].vi.vi_chn;
|
|
sample_comm_sys_vi_unbind_vpss(vi_pipe, vi_chn, vpss_pipe, vpss_ichn);
|
|
|
|
vpss_config = &g_stream[id].vpss.vpss_cfg;
|
|
sample_comm_vpss_stop(vpss_config);
|
|
|
|
isp_param = &g_stream[id].isp.isp_param;
|
|
sample_comm_isp_stop(isp_param);
|
|
|
|
vi_config = &g_stream[id].vi.vi_cfg;
|
|
sample_comm_vi_stop(vi_config);
|
|
|
|
sample_comm_isp_exit(isp_param);
|
|
|
|
id++;
|
|
}
|
|
|
|
sample_dual_sys_deinit();
|
|
|
|
g_start = 0;
|
|
|
|
return 0;
|
|
}
|